1

I have an input box which the user types text into. I'm using the inputted text and replacing a portion of a large text file.

The problem is, if the user inputs the $& characters it will result in a lastMatch instead of the literal text which is of course a dollar sign ($) followed by an ampersand (&) without any special meaning.

You can see the user input here:

user input

To simulate the user input, I wrote the following code:

var originalString = "# Mandatory parameter\n#EPCDatabase/EPCdatabase.param/epc.db.user=\n# Mandatory parameter";

var regexExpression = new RegExp('#EPCDatabase\/EPCdatabase.param\/epc.db.user=.*$', "im");
var replaceSting = "EPCDatabase\/EPCdatabase.param\/epc.db.user=test#$#%^%>$&<%(*"
var newPropertiesText = originalString.replace(regexExpression, replaceSting);

console.log(originalString);
console.log(newPropertiesText);

The problem is that instead of appending the $& literally, it will append the lastMatch, and the newPropertiesText created as follows:

last match

As explained here, I've tried escaping the $ with two $$, so it will mean a literal dollar instead of the special combination:

"EPCDatabase\/EPCdatabase.param\/epc.db.user=aaaa#$#%^%>$&<%(*".replace(/\$&/g, '$$&');
                                   here is the problem  ^^

But that didn't help, so I tried different combination of \\$\\$ and similar patterns. But I couldn't send to the regex a simple $& literal.

EDIT: Using this escape function didn't solve the issue:

RegExp.escape= function(s) {
    return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};

var originalString = "# Mandatory parameter\n#EPCDatabase/EPCdatabase.param/epc.db.user=\n# Mandatory parameter";

var regexExpression = new RegExp('#EPCDatabase\/EPCdatabase.param\/epc.db.user=.*$', "im");
var replaceSting = RegExp.escape("EPCDatabase\/EPCdatabase.param\/epc.db.user=aaaa#$#%^%>$&<%(*");
var newPropertiesText = originalString.replace(regexExpression, replaceSting);
console.log(originalString);
console.log(newPropertiesText);

You can see it still returns the lastMatch.

Community
  • 1
  • 1
Alon Adler
  • 3,984
  • 4
  • 32
  • 44
  • Possible duplicate of [Is there a RegExp.escape function in Javascript?](http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript) – Laurel Nov 16 '16 at 15:46
  • @Laurel please see my updated question – Alon Adler Nov 16 '16 at 15:52

1 Answers1

2

So, after additional reading, thinking, some tries and additional #FFFFFF hairs, I got what it takes to solve this issue.

In order to tell the regex to put a literal $& instead of the entire match, you'll have to use the following:

.replace(/\$&/, '$$$$&')

$$ tells the regex engine one literal dollar sign, $$$$ tells it two literal dollar signs -> and two literal dollar signs one after the other in the replacement string actually become one literal dollar sign $. Followed by an & its become a normal literal $& without last match meaning.

var originalString = "# Mandatory parameter\n#EPCDatabase/EPCdatabase.param/epc.db.user=\n# Mandatory parameter";

var regexExpression = new RegExp('#EPCDatabase\/EPCdatabase.param\/epc.db.user=.*$', "im");
var replaceSting = "EPCDatabase\/EPCdatabase.param\/epc.db.user=aaaa#$#%^%>$&<%(*".replace(/\$&/, '$$$$&');
var newPropertiesText = originalString.replace(regexExpression, replaceSting);
console.log(originalString);
console.log(newPropertiesText);

You can view the code here if you want to play with it.

Alon Adler
  • 3,984
  • 4
  • 32
  • 44