0

I have the following text

text(-) 3

Which I want to change into:

-3

So I wrote the following regular expression:

'text(-) 3'.replace(/text\((?:[^\)]+)\)/g, RegExp.$1);

DEMO - which doesn't work.

However, when I do the following

var output = 'text(-) 3'.replace(/text\(([^\)]+)\)/g, RegExp.$1);
output = 'text(-) 3'.replace(/text\((?:[^\)]+)\)/g, RegExp.$1);

(So in the first I've removed the ?:) it works

DEMO

So there must be something I've missed with grouping matches with regular expressions (or just something stupid). Any help would be appreciated!?

2
  • Maybe better use 'text(-) 3'.replace(/[^-\d]/g, ''); ? Commented Dec 15, 2014 at 14:58
  • I can't, because in my case other text can be present in the string which I don't want to replace and I really would like to know whats going on here! Commented Dec 15, 2014 at 15:01

2 Answers 2

2

Code explanation

Removing ?: makes the group capturing, which means that it will capture anything matched by [^\)]+, and the matched text is made available for replacement and backreference.

var output = 'text(-) 3'.replace(/text\(([^\)]+)\)/g, RegExp.$1);

When String.replace is called, RegExp.$1 is not yet initialized, so the result in output will be " 3". Then the regex is executed, and the capturing group captures - in text(-) and place it in capturing group 1.

The deprecated attribute RegExp.$1 is also updated with the content of the capturing group 1 of the last RegExp execution.

Then on the next line:

output = 'text(-) 3'.replace(/text\((?:[^\)]+)\)/g, RegExp.$1);

Since RegExp.$1 now contains "-", the replacement give the result "- 3".

RegExp.$1 is deprecated, since it is shared between all execution of RegExp and extremely error prone. So are a bunch of other properties RegExp.$2 to RegExp.$9 which contains the content of the capturing group 2 to 9 of the latest execution.

Solution

For your purpose, you should do this:

var output = 'text(-) 3'.replace(/text\(([^\)]+)\) */g, "$1");

It is not clear how many spaces after ), so I added  *. To refer to the content of a capturing group in the replacement, use $1 in the replacement string.

Sign up to request clarification or add additional context in comments.

Comments

1

You might be looking for

var output = 'text(-) 3'.replace(/text\(([^\)]+)\)/g, '$1');

Fiddle Demo

Problems with 'text(-) 3'.replace(/text\((?:[^\)]+)\)/g, RegExp.$1);

  • (?:[^\)]+) is a non capturing group so the value is not captured in $1

  • RegExp.$1 Contains the capture group from the previous regex match and not the current

    That is

    var output = 'text(-) 3'.replace(/text\(([^\)]+)\)/g, RegExp.$1);
    output = 'text(-) 3'.replace(/text\((?:[^\)]+)\)/g, RegExp.$1);
    

    Here in the second statement the regex RegExp.$1 is from the first statement and not from the second. So when used alone it is unset and does not create the expected output.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.