我有一个看起来像这样的字符串:
var str = "Hello world, hello >world, hello world!";
...我想用例如替换所有的hellos再见和世界与地球,除了以& nbsp或& gt开头的单词。那些应该被忽略。所以结果应该是:
bye earth, hello >world, bye earth!
尝试
str.replace(/(?!\ )hello/gi,'bye'));
但它不起作用。
答案 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);