在下面的正则表达式中,\s表示空格字符。我想象正则表达式解析器,正在遍历字符串,看到\,知道下一个字符是特殊的。但事实并非如此,因为需要双重转义。为什么会这样呢?
\s
\
var res = new RegExp('(\\s|^)' + foo).test(moo);
有没有一个具体的例子,说明一次逃跑是如何被误解为其他事情的?
kyxcudwk1#
通过向RegExp构造函数传递字符串来构造正则表达式。\是字符串字面量中的转义字符。\被字符串字面量解析所消耗。
const foo = "foo"; const string = '(\s|^)' + foo; console.log(string);
.所以传递给RegEx编译器的数据是普通的s而不是\s。您需要对\进行转义,以将\表示为数据,而不是转义字符本身。
s
mtb9vblg2#
在创建字符串的代码中,反斜杠首先是一个JavaScript转义字符,这意味着像\t,\n,\"等转义序列。将被翻译成对应的JavaScript(制表符,换行符,引号等),这将成为字符串的一部分。双反斜杠表示实际字符串本身中的单个反斜杠,因此,如果您希望字符串中有反斜杠,请首先转义它。所以当你通过var someString = '(\\s|^)'生成一个字符串时,你实际上是在创建一个值为(\s|^)的实际字符串。
\t
\n
\"
var someString = '(\\s|^)'
(\s|^)
tct7dpnv3#
Regex需要\s的字符串表示,在JavaScript中可以使用文字"\\s"生成。这里有一个活生生的例子来说明为什么"\s"是不够的:
"\\s"
"\s"
alert("One backslash: \s\nDouble backslashes: \\s");
注意\s之前的额外\如何改变输出。
ycl3bljg4#
如前所述,在字符串字面量中,反斜杠表示转义序列,而不是字面量反斜杠字符,但RegExp构造函数通常需要传递给它的字符串中的字面量反斜杠字符,因此代码应该有\\ s来表示字面量反斜杠,* 在大多数情况下 *。一个问题是,双重转义元字符是乏味的。有一种方法可以将一个字符串传递给new RegExp,而不必对它们进行双重转义:使用String.raw模板标签,这是ES6的一个特性,它允许你编写一个将被解释器解析的字符串,而不需要解析任何转义序列。举例来说:
\\
new RegExp
String.raw
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));
pkln4tw65#
\在字符串中用于转义特殊字符。如果你想在字符串中使用反斜杠(例如,对于\ in \s),您必须通过反斜杠对其进行转义。所以变成了。编辑:甚至不得不在这里这样做,因为\在我的回答转向\。
5条答案
按热度按时间kyxcudwk1#
通过向RegExp构造函数传递字符串来构造正则表达式。
\
是字符串字面量中的转义字符。\
被字符串字面量解析所消耗。.所以传递给RegEx编译器的数据是普通的
s
而不是\s
。您需要对
\
进行转义,以将\
表示为数据,而不是转义字符本身。mtb9vblg2#
在创建字符串的代码中,反斜杠首先是一个JavaScript转义字符,这意味着像
\t
,\n
,\"
等转义序列。将被翻译成对应的JavaScript(制表符,换行符,引号等),这将成为字符串的一部分。双反斜杠表示实际字符串本身中的单个反斜杠,因此,如果您希望字符串中有反斜杠,请首先转义它。所以当你通过
var someString = '(\\s|^)'
生成一个字符串时,你实际上是在创建一个值为(\s|^)
的实际字符串。tct7dpnv3#
Regex需要
\s
的字符串表示,在JavaScript中可以使用文字"\\s"
生成。这里有一个活生生的例子来说明为什么
"\s"
是不够的:注意
\s
之前的额外\
如何改变输出。ycl3bljg4#
如前所述,在字符串字面量中,反斜杠表示转义序列,而不是字面量反斜杠字符,但RegExp构造函数通常需要传递给它的字符串中的字面量反斜杠字符,因此代码应该有
\\
s来表示字面量反斜杠,* 在大多数情况下 *。一个问题是,双重转义元字符是乏味的。有一种方法可以将一个字符串传递给
new RegExp
,而不必对它们进行双重转义:使用String.raw
模板标签,这是ES6的一个特性,它允许你编写一个将被解释器解析的字符串,而不需要解析任何转义序列。举例来说:所以,如果你想保持代码的可读性,并且你有很多反斜杠,当模式需要一个反斜杠时,你可以使用
String.raw
只输入 * 一个 * 反斜杠:**但是还有一个更好的选择。**一般来说,没有太多好的理由使用
new RegExp
,除非你需要从现有的变量动态创建一个正则表达式。否则,你应该使用正则表达式,它不需要对元字符进行双重转义,也不需要写出String.raw
来保持模式的可读性:最好只在必须动态创建模式时使用
new RegExp
,如以下代码片段所示:pkln4tw65#
\在字符串中用于转义特殊字符。如果你想在字符串中使用反斜杠(例如,对于\ in \s),您必须通过反斜杠对其进行转义。所以变成了。
编辑:甚至不得不在这里这样做,因为\在我的回答转向\。