2021年10月25日

转义,特殊字符

正如我们所见,反斜杠 \ 用于表示字符类,例如 \d。因此,它在正则表达式中是一个特殊字符(就像在普通字符串中一样)。

还有一些其他特殊字符,它们在正则表达式中也有特殊含义,例如 [ ] { } ( ) \ ^ $ . | ? * +。它们用于进行更强大的搜索。

不要试图记住这个列表——很快我们就会处理其中的每一个,你就会自动地记住它们。

转义

假设我们想要找到一个字面上的点。不是“任何字符”,而只是一个点。

要将特殊字符用作普通字符,请在前面加上反斜杠:\.

这也称为“转义字符”。

例如

alert( "Chapter 5.1".match(/\d\.\d/) ); // 5.1 (match!)
alert( "Chapter 511".match(/\d\.\d/) ); // null (looking for a real dot \.)

圆括号也是特殊字符,因此如果我们想要使用它们,我们应该使用 \(。下面的示例查找字符串 "g()"

alert( "function g()".match(/g\(\)/) ); // "g()"

如果我们正在查找反斜杠 \,它在普通字符串和正则表达式中都是特殊字符,因此我们应该将其加倍。

alert( "1\\2".match(/\\/) ); // '\'

斜杠

斜杠符号 '/' 不是特殊字符,但在 JavaScript 中它用于打开和关闭正则表达式:/...pattern.../,因此我们也应该对其进行转义。

以下是查找斜杠 '/' 的示例

alert( "/".match(/\//) ); // '/'

另一方面,如果我们没有使用 /.../,而是使用 new RegExp 创建正则表达式,那么我们就不需要对其进行转义

alert( "/".match(new RegExp("/")) ); // finds /

new RegExp

如果我们使用 new RegExp 创建正则表达式,那么我们就不必转义 /,但需要进行其他转义。

例如,考虑以下情况

let regexp = new RegExp("\d\.\d");

alert( "Chapter 5.1".match(regexp) ); // null

之前示例中类似的搜索使用 /\d\.\d/,但 new RegExp("\d\.\d") 不起作用,为什么?

原因是反斜杠被字符串“消耗”。正如我们可能记得的那样,普通字符串有自己的特殊字符,例如 \n,并且反斜杠用于转义。

以下是“\d.\d”的感知方式

alert("\d\.\d"); // d.d

字符串引号“消耗”反斜杠并自行解释它们,例如

  • \n – 变成换行符,
  • \u1234 – 变成具有此代码的 Unicode 字符,
  • …当没有特殊含义时:例如 \d\z,则反斜杠将被简单地删除。

因此 new RegExp 获取一个没有反斜杠的字符串。这就是搜索不起作用的原因!

要修复它,我们需要加倍反斜杠,因为字符串引号将 \\ 变成 \

let regStr = "\\d\\.\\d";
alert(regStr); // \d\.\d (correct now)

let regexp = new RegExp(regStr);

alert( "Chapter 5.1".match(regexp) ); // 5.1

总结

  • 要按字面搜索特殊字符 [ \ ^ $ . | ? * + ( ),我们需要在前面加上反斜杠 \(“转义它们”)。
  • 如果我们在 /.../ 中(但不在 new RegExp 中),我们还需要转义 /
  • 当将字符串传递给new RegExp时,我们需要使用双反斜杠\\,因为字符串引号会消耗其中一个。
教程地图

评论

在评论之前请阅读…
  • 如果您有任何改进建议,请提交 GitHub 问题或拉取请求,而不是评论。
  • 如果您无法理解文章中的内容,请详细说明。
  • 要插入几行代码,请使用<code>标签,对于多行代码,请将其包装在<pre>标签中,对于超过 10 行的代码,请使用沙盒(plnkrjsbincodepen…)