【问题标题】:Regular Expression - Match String Not Preceded by Another String (JavaScript)正则表达式 - 匹配字符串前面没有另一个字符串 (JavaScript)
【发布时间】:2013-09-18 23:57:35
【问题描述】:

我试图找到一个正则表达式,当它前面没有另一个特定字符串时(在我的例子中,当它前面没有“http://”时)将匹配一个字符串。这是在 JavaScript 中,我在 Chrome 上运行(没关系)。

示例代码为:

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

我想用一个正则表达式替换 SOMETHING,意思是“匹配 www.stackoverflow.com,除非它前面有 http://”。然后警报自然会说“http://www.stackoverflow.comrocks”。

有人可以帮忙吗?感觉就像我尝试了以前答案中的所有内容,但没有任何效果。谢谢!

【问题讨论】:

  • 阅读“负前瞻”。
  • 技术上,整个字符串前面没有http://;是否应该整体更换?
  • 未捕获的语法错误:无效的正则表达式:/(?
  • JS 正则表达式引擎不支持lookbehinds。
  • 我正在寻找的只是一个正则表达式,它允许我在 JavaScript 中匹配字符串 XXX,如果它前面没有 YYY。

标签: javascript regex


【解决方案1】:

由于 JavaScript 正则表达式引擎不支持“lookbehind”断言,因此不可能使用纯正则表达式。不过,有一个解决方法,涉及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);

您实际上可以为这些函数创建一个生成器:

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

...然后在 replace 中使用它:

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

JS Fiddle.

【讨论】:

    【解决方案2】:

    raina77ow 的回答反映了 2013 年的情况,但现在已经过时了,因为 the proposal for lookbehind assertions 在 2018 年被 ECMAScript 规范接受。

    docs for it on MDN:

    Characters Meaning
    (?<!y)x Negative lookbehind assertion: Matches "x" only if "x" is not preceded by "y". For example, /(?<!-)\d+/ matches a number only if it is not preceded by a minus sign. /(?<!-)\d+/.exec('3') matches "3". /(?<!-)\d+/.exec('-3') match is not found because the number is preceded by the minus sign.

    因此,您现在可以将“匹配www.stackoverflow.com,除非它前面有http://”表示为/(?<!http:\/\/)www.stackoverflow.com/

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

    【讨论】:

      【解决方案3】:

      这也有效:

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

      警报显示“http://www.example.comrocks”。

      【讨论】:

      • 它有效,但不是您认为的那样。基本上,当使用字符类正则表达式运算符时,您只是替换不在 'htps:/()|' 中的任何符号序列范围,后跟www.example.com。首先,它会给您带来很多误报,其次,它显然是多余的。
      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      相关资源
      最近更新 更多