views:

1711

answers:

4

I've been trying to find a way to match a number in a Javascript string that is surrounded by parenthesis at the end of the string, then increment it.

Say I have a string:

var name = "Item Name (4)";

I need a RegExp to match the (4) part, and then I need to increment the 4 then put it back into the string.

This is the regex I have so far:

\b([0-9]+)$\b

This regex does not work. Furthermore, I do not know how to extract the integer retrieved and put it back in the same location in the string.

Thanks.

A: 

I can can only think of a way of doing it in three steps: Extract, increment and replace.

// Tested on rhino
var name = "Item Name (4)";
var re = /\((\d+)\)/;

match = re.exec(name);
number = parseInt(match[1]) + 1;
name = name.replace(re, "(" + number + ")");

The important parts of the pattern:

  1. You need to escape the parens to match literal parens
  2. You also need the to use parens to capture the number so that you can extract it from the match.
  3. \d matches a digit and is shorter and more common than writing out [0-9].
Aaron Maenpaa
A: 

'var name = "Item Name (4)"'.replace(/\(([\d]+)\)/, 1 + $1);

(untested)

Throws an error in rhino:

js> "Item Name (4)".replace(/\(([0-9]+)\)/, 1 + $1)
js: "<stdin>", line 5: uncaught JavaScript runtime exception: ReferenceError: "$1" is not defined.
It's much more consise though ;-)
A: 

In order this pattern to work you shoud escape parenthesis. In addition \b and $ are unneeded. Thus

var s = "Item Name (4)"; 
var match = /\((\d+)\)/.exec( s ); 
var n = Number(match[1])+1; 
alert( s.replace( /\(\d+\)/, '('+n+')' ) );

Solution by david.clarke (tested)

"Item Name (4)".replace(/\(([0-9]+)\)/, '('+(1+RegExp.$1) + ')');

But I think it is too concise

UPD: It turned out that RegExp.$1 can't be used as part of replace parameter, because it works only in Opera

x-yuri
1 + RegExp.$1 always returns 1 for me.
nickf
yes, I see. I tested in Opera only
x-yuri
+8  A: 

The replace method can take a function as its second argument. It gets the match (including submatches) and returns the replacement string. Others have already mentioned that the parentheses need to be escaped.

"Item Name (4)".replace(/\((\d+)\)/, function(fullMatch, n) {
    return "(" + (Number(n) + 1) + ")";
});
Matthew Crumley
This is the right way to do it. Often the function form of replace is the only convenient way to combine the power of the builtin-regexp scanner, with the free-form power of user-defined functions. I've even used closures to have "stateful" functions with replace().
Jason S