B-and-P
B-and-P

Reputation: 1713

Javascript regex replace yields unexpected result

I have this strange issue, hope that someone will explain what is going on.

My intention is to capture the textual part (a-z, hyphen, underscore) and append the numeric values of id and v to it, underscore separated.

My code:

var str_1 = 'foo1_2';
var str_2 = 'foo-bar1_2';
var str_3 = 'foo_baz1_2';
var id = 3;
var v = 2;
str_1 = str_1.replace(/([a-z_-]+)\d+/,'$1' + id + '_' + v);
str_2 = str_2.replace(/([a-z_-]+)\d+/,'$1' + id + '_' + v);
str_3 = str_3.replace(/([a-z_-]+)\d+/,'$1' + id + '_' + v);

$('#test').html(str_1 + '<br>' + str_2 + '<br>' + str_3 + '<br>');

Expected result:

foo3_2
foo-bar3_2
foo_baz3_2 

Actual Result:

foo3_2_2
foo-bar3_2_2
foo_baz3_2_2

Any ideas?

JS Fiddle example

Upvotes: 1

Views: 69

Answers (5)

parameciostudio
parameciostudio

Reputation: 590

Your pattern actually includes the first digits, but it will store only the textual part into $1:

foo1_2

([a-z_-]+)\d+   = foo1
$1              = foo 

The pattern stops searching at the first digits of the string. if you want to replace any characters after the textual part, you could use this pattern:

/([a-z_-]+)\d+.*/

Upvotes: 0

Manwal
Manwal

Reputation: 23816

Because you want to replace _2 also of string. Solution can be this:

str_1 = str_1.replace(/([a-z_-]+)\d+_\d/,'$1' + id + '_' + v);
str_2 = str_2.replace(/([a-z_-]+)\d+_\d/,'$1' + id + '_' + v);
str_3 = str_3.replace(/([a-z_-]+)\d+_\d/,'$1' + id + '_' + v);

DEMO

Upvotes: 0

Pieter21
Pieter21

Reputation: 1845

Use this instead to capture 1_2 completely:

str_1 = str_1.replace(/([a-z_-]+)\d+_\d+/,'$1' + id + '_' + v);

Upvotes: 0

hsz
hsz

Reputation: 152206

Just try with:

str_1 = str_1.match(/([a-z_-]+)\d+/)[1] + id + '_' + v;

Upvotes: 0

Pointy
Pointy

Reputation: 413702

Your pattern:

/([a-z_-]+)\d+/

matches only "foo1" in "foo1_2", and "foo" will be the value of the captured group. The .replace() function replaces the portion of the source string that was actually matched, leaving the remainder alone. Thus "foo1" is replaced by "foo3_2", but the original trailing "_2" is still there as well.

If you want to alter the entire string, then your regular expression will have to account for everything in the source strings.

Upvotes: 4

Related Questions