Regex find and replace same number of repeated characters


#1

In a restructured text, I want to find the characters used for sectioning, e.g. ======== and replace them with the same number of dashes: --------
For finding, I successfully used (^==*$), even though I do not full yunderstand it (it expected that I have to use only one =). To find that expression, I used https://regex101.com/
For replacing, I need something like length($1) but I was not able to find a working solution. Is some operator like length() allowed/supported?
And, in general, is the regex find and replace documented anywhere?


#2

AFAIK you won’t be able to achieve that with only the find-and-replace dialog as it is now. But I’ve looked at how to do that, and you can use this snippet in the devtools console to perform the replacements:

e = atom.workspace.getActiveTextEditor()
e.scan(/=+/g, (r) => { e.setTextInBufferRange(r.computedRange, new Array(r.matchText.length + 1).join('-')) })

#3

Thanks, so that is a javascript solution, correct? Never used the console before.
I have filed a feature request with the find&replace package:


Maybe they can use your code directly tom implement that length() thing?


#4

Atom passes your search & replace query to the javascript regex engine, and that engine do not support the length($1) or repeat operation you describe. I don’t really know one regex engine that does it.

Arbitrary code is more flexible than regex, and to that extend abe solution look fitting. If you need to use the thing more often than once maybe register a command to to it.


#5

One possibility, though, would be to have a mode that allow the replacement string to be javascript code used to build a replacement method through new Function(sign, code). But I fear that doing so would require a lot of care in design phase and a lot of mistakes must be accounted for since the use can basically break everything through that feature.


#6

Just as an aside, the reason you’re using two ='s, is because * means zero or more, meaning with only one it matches anything with no ='s. In this case, you’re specifying a start and end, but otherwise it would match things that both do and don’t have an equals. So by having that first =, you’re ensuring that you have at least one equals, and the second with the * is checking for any additional ='s.

You could only use one, by using + rather than *, which means one or more (like: ^=+$).


#7

Thansk for all the help and explanation!