匹配不以.开头的字符串

Pin*_*nky 0 javascript regex

我有一个看起来像这样的字符串:

var str = "Hello world,  hello >world, hello world!";
Run Code Online (Sandbox Code Playgroud)

......我想用地球替换所有的hellos,例如bye和world,除了以 或>开头的单词.那些应该被忽略.所以结果应该是:

bye earth,  hello >world, bye earth!
Run Code Online (Sandbox Code Playgroud)

试过这个

str.replace(/(?!\ )hello/gi,'bye'));
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

Mar*_*der 6

(?!...)是一个展望未来.所以它会查看您想要匹配的相同字符hello.你需要的是一个外观.

不幸的是,JavaScript不支持lookbehinds.但是你可以反转字符串和模式:

reverse = function(s){
    return s.split("").reverse().join("");
}

str = reverse(reverse(str).replace(/olleh(?!;psbn&)/gi, 'eyb'));
Run Code Online (Sandbox Code Playgroud)

我承认,有点黑客攻击.

或者,可以应用这样的解决方案.它依赖于匹配不能重叠的事实:

str = str.replace(/( hello)|hello/ig, function(match, firstGroup) {
    return firstGroup ? firstGroup : "bye"
});
Run Code Online (Sandbox Code Playgroud)

但是,使用稍微更加神秘的技巧(如链接的答案),您可以将效率提高大约2倍:

str = str.replace(/$/, "bye")                            
         .replace(/( hello)|hello(?=.*(bye))/g, "$1$2")
         .replace(/bye$/, "")
Run Code Online (Sandbox Code Playgroud)

有关完整说明,请参阅其他帖子(因为此问题基本上是重复的).

至于性能,反转的显然是最慢的,因为它必须处理一个数组(两次).至于其他的,回调一个是最快的,正则表达只有一个介于两者之间.因此,无论是性能还是可读性,我都建议使用回调解决方案.(见基准)