Regex replacement involving dollar signs behaves weirdly


#1

I wanted to open this topic to possibly report a bug in the software involving the text matching and replacement with the regular expressions feature activated.

I have a Bash script where I wanted to quote all values from parameters and store them in the appropriate variables, so to do that I used the following lines entered verbatim after the colon and single space:
Match Expression: =$(.*?);
Replace Expression: ="$$1";

I had figured instead of using \1 to insert a matched group that it is apparently a Perl-style regular expression engine, so I switched to using $1, but I realized this was not inserting the matched group, and instead the literal $1 with quotes surrounding it into each right-hand assignment. I realize this is because $$ in the resulting expression was resolved first, causing a literal dollar sign to be outputted, and then a literal 1 character, but note how I did not need a backslash in the Replace Expression to have a literal dollar sign to be outputted since that backslash would be outputted as well. In order to have it work, I had to use the following:
Match Expression: =$(.*?);
Replace Expression: ="$$$1";

Is this a problem with Atom’s implementation that could be modified? My suggestion if I were to take a stab at fixing the grammar, is that both $ and $$ both resolve to a literal dollar sign when used in the Replace Expression. That is ambiguous, especially when trying to insert a matched group directly after it, so have a single dollar sign resolve to printing that character, so the second will trigger an escape character expression.


#2

I’m pretty certain that the find-and-replace package uses either JavaScript or Oniguruma regular expressions. So while the regular expression grammar could be changed, I’m not sure if it would be an easy change … you’d probably have to change it upstream.

@abe, do you know more about this? I seem to remember you correcting my understanding of this in the past :laughing:


#3

Looking at the source it just call the String::replace method and a plain old RegExp object:

https://github.com/atom/find-and-replace/blob/master/lib/find-model.coffee#L65-L66

So everything in the spec should be available:

And as you can see in this section, $$ is how you insert a $ in the replacement string:

So $$1 will output $1, so that you can replace stuff to generate replacement strings, for instance. And a $ alone doesn’t count as a replacement.