Javascript正则表达式替换会产生意外结果

时间:2015-08-25 12:26:13

标签: javascript regex

我有这个奇怪的问题,希望有人能解释发生了什么。

我的目的是捕获文本部分(a-z,连字符,下划线)并将idv的数值附加到其中,以下划线分隔。

我的代码:

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>');

预期结果:

foo3_2
foo-bar3_2
foo_baz3_2 

实际结果:

foo3_2_2
foo-bar3_2_2
foo_baz3_2_2

有什么想法吗?

JS Fiddle example

5 个答案:

答案 0 :(得分:4)

你的模式:

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

仅匹配“foo1_2”中的“foo1”,“foo”将是捕获组的值。 .replace()函数替换实际匹配的源字符串部分,剩下的部分单独使用。因此“foo1”被“foo3_2”取代,但原始的尾部“_2”仍然存在。

如果你想改变整个字符串,那么你的正则表达式必须考虑源字符串中的所有内容。

答案 1 :(得分:0)

试试:

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

答案 2 :(得分:0)

使用它来完全捕获1_2:

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

答案 3 :(得分:0)

因为你想要替换字符串的_2。解决方案可以是这样的:

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

答案 4 :(得分:0)

您的模式实际上包含第一个数字,但它只会将文本部分存储到$ 1:

foo1_2

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

模式停止搜索字符串的第一个数字。 如果要替换文本部分之后的任何字符,可以使用以下模式:

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