我有一个看起来像这样的字符串:
var str = "Hello world, hello >world, hello world!";
...我想用例如再见和地球替换所有的你好,除了以 或> 开头的单词。这些应该被忽略。所以结果应该是:
bye earth, hello >world, bye earth!
试过这个
str.replace(/(?!\ )hello/gi,'bye'));
但它不起作用。
我有一个看起来像这样的字符串:
var str = "Hello world, hello >world, hello world!";
...我想用例如再见和地球替换所有的你好,除了以 或> 开头的单词。这些应该被忽略。所以结果应该是:
bye earth, hello >world, bye earth!
试过这个
str.replace(/(?!\ )hello/gi,'bye'));
但它不起作用。
(?!...)
是向前看。因此,它会查看您要匹配的相同字符hello
。您需要的是向后看。
不幸的是,JavaScript 不支持lookbehinds。但是,您可以反转字符串和模式:
reverse = function(s){
return s.split("").reverse().join("");
}
str = reverse(reverse(str).replace(/olleh(?!;psbn&)/gi, 'eyb'));
我承认,这有点骇人听闻。
或者,可以应用这样的解决方案。它依赖于匹配不能重叠的事实:
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$/, "")
有关完整的解释,请参阅另一篇文章(因为这个问题本质上是重复的)。
至于性能,反转显然是最慢的,因为它必须处理一个数组(两次)。至于其他,回调是最快的,而正则表达式只有一个介于两者之间。所以无论是性能还是可读性,我都推荐回调解决方案。(见基准)
通常,您会使用否定的 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!
您可以捕获所有以
或开头的单词>
:
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);