简体   繁体   English

正则表达式 - 匹配字符串前面没有另一个字符串 (JavaScript)

[英]Regular Expression - Match String Not Preceded by Another String (JavaScript)

I am trying to find a regular expression that will match a string when it's NOT preceded by another specific string (in my case, when it is NOT preceded by "http://").我试图找到一个正则表达式,当它前面没有另一个特定字符串时(在我的例子中,当它前面没有“http://”时)将匹配一个字符串。 This is in JavaScript , and I'm running on Chrome (not that it should matter).这是在JavaScript中,我在 Chrome 上运行(没关系)。

The sample code is:示例代码是:

var str = 'http://www.stackoverflow.com www.stackoverflow.com';
alert(str.replace(new RegExp('SOMETHING','g'),'rocks'));

And I want to replace SOMETHING with a regular expression that means "match www.stackoverflow.com unless it's preceded by http://".我想用一个正则表达式替换 SOMETHING,意思是“匹配 www.stackoverflow.com,除非它前面有 http://”。 The alert should then say " http://www.stackoverflow.com rocks", naturally.然后警报自然会说“ http://www.stackoverflow.com Rocks”。

Can anyone help?任何人都可以帮忙吗? It feels like I tried everything found in previous answers, but nothing works.感觉就像我尝试了以前答案中的所有内容,但没有任何效果。 Thanks!谢谢!

As JavaScript regex engines don't support 'lookbehind' assertions, it's not possible to do with plain regex. 由于JavaScript正则表达式引擎不支持“lookbehind”断言,因此无法使用普通正则表达式。 Still, there's a workaround, involving replace callback function: 仍然有一个解决方法,涉及replace回调函数:

var str = "As http://JavaScript regex engines don't support `lookbehind`, it's not possible to do with plain regex. Still, there's a workaround";

var adjusted = str.replace(/\S+/g, function(match) {
  return match.slice(0, 7) === 'http://'
    ? match
    : 'rocks'
});
console.log(adjusted);

You can actually create a generator for these functions: 您实际上可以为这些函数创建一个生成器:

var replaceIfNotPrecededBy = function(notPrecededBy, replacement) {
   return function(match) {
     return match.slice(0, notPrecededBy.length) === notPrecededBy
       ? match
       : replacement;
   }
};

... then use it in that replace instead: ...然后在replace使用它:

var adjusted = str.replace(/\S+/g, replaceIfNotPrecededBy('http://', 'rocks'));

JS Fiddle . JS小提琴

This also works: 这也有效:

var variable = 'http://www.example.com www.example.com';
alert(variable.replace(new RegExp('([^(http:\/\/)|(https:\/\/)])(www.example.com)','g'),'$1rocks'));

The alert says " http://www.example.com rocks". 警报说“ http://www.example.com rocks”。

raina77ow's answer reflected the situation in 2013, but it is now outdated, as the proposal for lookbehind assertions<\/a> got accepted into the ECMAScript spec in 2018.<\/strong> Raina77ow 的回答反映了 2013 年的情况,但现在已经过时了,因为关于后向断言的提议<\/a>在 2018 年被 ECMAScript 规范接受。<\/strong>

See docs for it on MDN<\/a> :请参阅MDN 上的文档<\/a>:

Characters人物<\/th> Meaning意义<\/th><\/tr><\/thead>
(?<!y)x<\/code><\/td> Negative lookbehind assertion:<\/strong> Matches "x" only if "x" is not preceded by "y".否定后向断言:<\/strong>仅当“x”前面没有“y”时才匹配“x”。 For example, \/(?<!-)\\d+\/<\/code> matches a number only if it is not preceded by a minus sign.例如, \/(?<!-)\\d+\/<\/code>仅匹配前面没有减号的数字。 \/(?<!-)\\d+\/.exec('3')<\/code> matches "3". \/(?<!-)\\d+\/.exec('3')<\/code>匹配“3”。 \/(?<!-)\\d+\/.exec('-3')<\/code> match is not found because the number is preceded by the minus sign. \/(?<!-)\\d+\/.exec('-3')<\/code>匹配未找到,因为数字前面有减号。<\/td><\/tr><\/tbody><\/table><\/blockquote>

Therefore, you can now express "match www.stackoverflow.com<\/code> unless it's preceded by http:\/\/<\/code> " as \/(?<!http:\\\/\\\/)www.stackoverflow.com\/<\/code> :因此,您现在可以将“匹配www.stackoverflow.com<\/code>除非它前面有http:\/\/<\/code> ”表示为\/(?<!http:\\\/\\\/)www.stackoverflow.com\/<\/code> :

 const str = 'http:\/\/www.stackoverflow.com www.stackoverflow.com'; console.log(str.replace(\/(?<!http:\\\/\\\/)www.stackoverflow.com\/g, 'rocks'));<\/code><\/pre>

"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM