我在MDN documentation中遇到了在字符串上使用replace方法的示例。

这是那里引用的例子

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
print(newstr);//Smith,John


我将正则表达式更改为以下内容并对其进行了测试。

var re = /(\w?)(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$1, $1");
newstr;//J, ohn Smith
var newstr1=str.replace(re,"$2, $1");
newstr1;//ohn, J Smith.


在此示例中,$ 1必须为J,$ 2必须为ohn Smith
当我将newstr1的$ n顺序颠倒时,它应该是'ohn Smith,J`。但事实并非如此。

是我对$ 1和$ 2(子字符串匹配正确)的理解,为什么newstr1不同?

感谢您的评论

最佳答案

实际上,$1"J"$2"ohn",并且" Smith"不匹配。

var re = /(\w?)(\w+)/,
    str = "John Smith";

str.replace(re, function (match, $1, $2) {
    console.log('match', match);
    console.log('$1', $1);
    console.log('$2', $2);
    return ''; // leave only unmatched
});
/* match John
   $1 J
   $2 ohn
   " Smith"
*/


因此,您的交换是在John之间切换,从而得到newstr1

为什么会这样呢?因为\w匹配一个单词,但是?使其成为可选单词,所以与(.*?)(.)捕获$1中的一个字母一样,(\w?)也是一样。然后,第二个捕获(\w+)只能扩展到单词的末尾,而忽略+,因为\w与空白\s不匹配。

10-01 14:24