为什么正则表达式构造函数需要双重转义?

Smu*_*tte 40 javascript regex

在下面的正则表达式中,\s表示空格字符.我想象正则表达式解析器,正在通过字符串看到\并知道下一个字符是特殊的.

但事实并非如此,因为需要双重逃脱.

为什么是这样?

var res = new RegExp('(\\s|^)' + foo).test(moo);
Run Code Online (Sandbox Code Playgroud)

是否有一个具体的例子说明单个逃避如何被误解为其他东西?

Que*_*tin 39

您正在通过将字符串传递给RegExp构造函数来构造正则表达式.

您需要转义它,\以便您的字符串文字可以在将其转换为正则表达式之前将其表示为数据.

  • 这既适用于常规字符串文字,也适用于模板字符串文字。 (2认同)

Joe*_*nos 17

在那里你要创建一个字符串的代码里面,反斜杠是一个JavaScript转义字符第一,这意味着像转义序列\t,\n,\",等将被翻译成其JavaScript对口(制表符,换行符,报价等),和这将成为字符串的一部分.双反斜杠表示实际字符串本身中的单个反斜杠,因此如果您想在字符串中使用反斜杠,则首先将其转义.

所以当你通过说出你生成一个字符串时var someString = '(\\s|^)',你真正在做的是创建一个带有值的实际字符串(\s|^).


Cri*_*scu 7

正则表达式需要一个字符串表示形式\s,该字符串表示形式可以在JavaScript中使用文字产生"\\s"

这是一个实时示例,说明原因"\s"还不够:

alert("One backslash:          \s\nDouble backslashes: \\s");
Run Code Online (Sandbox Code Playgroud)

注额外如何\\s改变输出。


sch*_*cht 6

\在字符串中用于转义特殊字符。如果要在字符串中使用反斜杠(例如,对于\ s中的\),则必须通过反斜杠对其进行转义。因此\变为\\。

编辑:甚至不得不在这里做,因为我的答案中的\\变成了\。


Cer*_*nce 5

如前所述,在字符串文字中,反斜杠表示转义序列,而不是文字反斜杠字符,但是RegExp构造函数通常在传递给它的字符串中需要文字反斜杠字符,因此代码应具有\\s来表示文字在大多数情况下都使用反斜杠。

问题在于,双转义的元字符是乏味的。有一种传递字符串new RegExp而不必两次转义的方法:使用String.raw模板标签,ES6功能,它允许您编写将由解释程序逐字解析的字符串,而无需任何转义序列的解析。例如:

console.log('\\'.length);           // length 1: an escaped backslash
console.log(`\\`.length);           // length 1: an escaped backslash
console.log(String.raw`\\`.length); // length 2: no escaping in String.raw!
Run Code Online (Sandbox Code Playgroud)

所以,如果你想保持你的代码的可读性,而且你有很多反斜杠,你可以使用String.raw输入只有一个当模式需要一个反斜杠反斜杠:

const sentence = 'foo bar baz';
const regex = new RegExp(String.raw`\bfoo\sbar\sbaz\b`);
console.log(regex.test(sentence));
Run Code Online (Sandbox Code Playgroud)

但是还有一个更好的选择。通常,new RegExp除非您需要根据现有变量动态创建正则表达式,否则没有太多使用的理由。否则,您应该改用正则表达式文字,这些文字不需要对元字符进行两次转义,也不需要String.raw为了保持模式可读性而写出来:

const sentence = 'foo bar baz';
const regex = /\bfoo\sbar\sbaz\b/;
console.log(regex.test(sentence));
Run Code Online (Sandbox Code Playgroud)

最好仅new RegExp在必须动态创建模式时使用,如以下代码片段所示:

const sentence = 'foo bar baz';
const wordToFind = 'foo'; // from user input

const regex = new RegExp(String.raw`\b${wordToFind}\b`);
console.log(regex.test(sentence));
Run Code Online (Sandbox Code Playgroud)