62

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

但情况并非如此,因为需要双重转义。

为什么是这样?

var res = new RegExp('(\\s|^)' + foo).test(moo);

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

4

5 回答 5

53

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

\是字符串文字中的转义字符。

\被字符串文字解析所消耗……</p >

const foo = "foo";
const string = '(\s|^)' + foo;
console.log(string);

…所以你传递给 RegEx 编译器的数据是普通的s而不是\s.

您需要转义以\将其表示\为数据,而不是转义字符本身。

于 2013-07-25T16:03:05.610 回答
22

在您创建字符串的代码中,反斜杠首先是一个 javascript 转义字符,这意味着像\t, \n,\"等这样的转义序列将被翻译成它们的 javascript 对应项(制表符、换行符、引号等),并且这将成为字符串的一部分。双反斜杠表示实际字符串本身中的单个反斜杠,因此如果您想要字符串中的反斜杠,请先将其转义。

因此,当您通过说生成字符串时var someString = '(\\s|^)',您真正在做的是创建一个具有值的实际字符串(\s|^)

于 2013-07-25T16:02:19.427 回答
11

正则表达式需要 的字符串表示\s,在 JavaScript 中可以使用文字来生成"\\s"

这是一个活生生的例子来说明为什么"\s"还不够:

alert("One backslash:          \s\nDouble backslashes: \\s");

请注意额外的\before如何\s更改输出。

于 2013-07-25T16:02:28.623 回答
6

\ 在字符串中用于转义特殊字符。如果您想在字符串中使用反斜杠(例如,对于 \s 中的 \),您必须通过反斜杠对其进行转义。所以 \ 变成 \\ 。

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

于 2013-07-25T16:04:31.840 回答
6

如前所述,在字符串文字中,反斜杠表示转义序列,而不是文字反斜杠字符,但 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!

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

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

但有一个更好的选择。new RegExp通常,除非您需要从现有变量动态创建正则表达式,否则没有太多使用的充分理由。否则,您应该改用正则表达式文字,它不需要对元字符进行双重转义,也不需要写出String.raw以保持模式可读:

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

最好仅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));

于 2019-04-22T10:42:59.500 回答