如果我使用变量而不是直接使用相应的字符串,为什么此正则表达式不起作用?

时间:2019-02-01 18:22:18

标签: javascript regex

这是我的代码:

function escape(str) {
  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\\\$&');
}

function replace(str, needle, replacement) {
  var expr = '([^\\[]*)(' +
      escape(needle) + ')([^\\]]*)';
  return str.replace(new RegExp(expr, 'g'), '$1' + replacement + '$3');
}

document.body.innerHTML += replace('hello() [hello()] test()', '()', '@');

问题是以下几行:

var expr = '([^\\[]*)(' +
  escape(needle) + ')([^\\]]*)';

如果我将其替换为

var expr = '([^\\[]*)(' +
  '\\(\\)' + ')([^\\]]*)';

有效。我不明白为什么无法使用escape函数的返回值。我的意思是,如果我使用它进行测试,它将准确返回\\(\\)

alert(escape('()'));

我怎么了?

无法正常工作:https://jsfiddle.net/rmof8pzv/
工作提琴:https://jsfiddle.net/gpoy2rbt/

2 个答案:

答案 0 :(得分:1)

问题来自escape函数'\\\\$&'中的双反斜杠,您不需要对其进行转义,因为它只需要像'\\$&'那样转义一次。因此,更改转义功能给了我预期的结果。

function escape(str) {
  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

答案 1 :(得分:1)

似乎您正在混淆反斜杠的转义。

您需要在字符串文字中转义反斜杠,因为反斜杠也用于转义其他字符。这意味着字符串 literal '\\'存储为\,如下所示:

console.log('\\');

在正则表达式中,您还需要使用单个反斜杠对字符进行转义,但是,如果在字符串文字中这样做,则由于上述原因,您需要对它们进行两次转义。这就是您的工作示例起作用的原因。但是,在escape()函数中,您将添加两个反斜杠而不是一个。只需将'\\\\$&'更改为'\\$&',它应该可以正常工作。

function escape(str) {
  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}

function replace(str, needle, replacement) {
  var expr = '([^\\[]*)(' +
      escape(needle) + ')([^\\]]*)';
  return str.replace(new RegExp(expr, 'g'), '$1' + replacement + '$3');
}

console.log(replace('hello() [hello()] test()', '()', '@'));