匹配不以。开头的字符串

时间:2013-06-28 16:03:15

标签: javascript regex

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

var str = "Hello world,  hello >world, hello world!";

...我想用例如替换所有的hellos再见和世界与地球,除了以& nbsp或& gt开头的单词。那些应该被忽略。所以结果应该是:

bye earth,  hello >world, bye earth!

尝试

str.replace(/(?!\ )hello/gi,'bye'));

但它不起作用。

3 个答案:

答案 0 :(得分:6)

(?!...)看上去是 。因此,它会查看您要匹配hello的相同字符。你需要的是一个后视。

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

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

str = reverse(reverse(str).replace(/olleh(?!;psbn&)/gi, 'eyb'));

有点黑客,我承认。

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

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

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

str = str.replace(/$/, "bye")                            
         .replace(/( hello)|hello(?=.*(bye))/g, "$1$2")
         .replace(/bye$/, "")

有关完整说明,请参阅另一篇文章(因为此问题基本上是重复的)。

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

答案 1 :(得分:1)

通常情况下,您使用negative look-behind,但JavaScript不支持。你可以这样做:

var str = "Hello world,  hello >world, hello world!";
str.replace(/(&(?:nbsp|gt);)?(?:(hello)|world)/gi, 
    function($0, $1, $2){ return $1 ? $0 : $2 ? 'bye' : 'earth'; });
// bye earth,  hello >world, bye earth!

答案 2 :(得分:1)

您可以首先捕获以 >开头的所有字词:

var str = "Hello world,  hello >world, hello world!";

str = str.replace(/(&(?:gt|nbsp);\w+)|(\bhello\b)|(\bworld\b)/gi, function (match,p1,p2,p3) { 
    if (p1) return p1;
    if (p2) return 'bye';
    if (p3) return 'earth'; });

    console.log(str);