4.1 对特殊字符进行转义
在介绍其他元字符的用法之前,我们认为应该先把特殊字符的转义问题向大家解释清楚。
元字符是一些在正则表达式里有着特殊含义的字符。英文句号 .
是一个元字符,它可以用来匹配任何一个单个字符(详见第二章)。类似地,左方括号 [
也是一个元字符,它标志着一个字符集合的开始(详见第三章)
因为元字符在正则表达式里有着特殊的含义,所以这些字符就无法用来代表它们本身。比如说,你不能使用一个 [
来匹配 "[" 本身,也不能使用 .
来匹配. 本身。来看一个例子,我们打算用一个正则表达式去匹配一个包含着 "[" 和 "]" 字符的 JavaScript 数组:
例 1
myArray[0]
let myArray = new Array(); ... if (myArray[0] == 0) { ... }
分析
在这个例子里,原始文本是一段 JavaScript 代码,正则表达式则是程序员在使用一个文本编辑器去编写 JavaScript 代码时经常会用到的搜索字符串。我们的本意是用这个正则表达式把代码里的 "myArray[0]" 记号找出来,可结果与预期完全不一样。为什么会这样?因为 [
和 ]
在正则表达式里是用来定义一个字符集合(而不是 "[" 和 "]" 本身)的元字符,所以, myArray[0]
将匹配 myArray 后面跟着一个该集合成员的情况,而那个集合只有一个成员 0。因此, myArray[0]
只能匹配到 "myArray0"。
正如我们在第二章里提到的那样,在元字符的前面加上一个反斜杠就可以对它进行转义,转义序列 \.
将匹配 "." 本身,转义序列 \[
将匹配 "[" 本身。每个元字符都可以通过给它加上有个反斜杠前级的办法来转义,如此得到的转义序列将匹配那个字符本身而不是它特殊的元字符含义。要想匹配 "[" 和 "]",就必须对这两个字符进行转义。下面的例子与刚才的问题完全一样,但我们这次对正则表达式里的元字符都进行了转义:
例 2
myArray\[0\]
let myArray = new Array();
...
if (myArray[0] == 0) {
...
}
分析
这次搜索取得了预期结果。 \[
匹配 "[", \]
匹配 "]",所以 myArray\[0\]
匹配到了 "myArray[0]"。
具体到这个例子,用一个正则表达式来进行搜索多少有点儿小题大做,因为一个简单的文本匹配操作已足以完成这一任务,而且还会更容易一些。但如果你想查找的不仅仅是 "myArray[0]",还包括了 "myArray[1]"、 "myArray[2]" 等,用一个正则表达式来进行搜索就很有必要了。具体做法是,对 [
和 ]
进行转义,再列出需要在它们之间得到匹配的字符。如果你想匹配数组元素 0 到 9,你构造出来的正则表达式应该是下面这个样子:
myArray\[[0-9]\]
任何一个元字符都可以通过给它加上一个反斜杠字符 \
作为前缀的办法来转义,能够被转义的元字符并不仅局限于我们这里提到的那几个。
配对的元字符(比如 [
或 ]
)不用作元字符时必须被转义,否则正则表达式分析器很可能会抛出一个错误•
对元字符进行转义需要用到字符。这意味着 \
字符也是一个元字符它的特殊含义是对其他元字符进行转义。正如你在第二章里看到的那样,在需要匹配 "\" 本身的时候,我们必须把它转义为 \\
。
例 3
看看下面这个简单的例子。例子中的原始文本是一个包含着反斜杠字符的文件路径(用于 DOS 和 Windows 系统),而我们想在一个 Linux 或 Unix 系统上使用这个路径.也就是说,我们需要把这个路径里的反斜杠字符 "\" 全部替换为正斜杠字符 "/":
\\
\home\hefang\DevDir\
分析
\\
匹配 "\" ,总共找到了 4 个匹配。如果你在这个正则表达式里只写出了一个 \
的话,你应该会看到一条出错消息。这是因为正则表达式分析器会认为你的正则表达式不完整,在一个完整的正则表达式里,字符 \
的后面永远跟着另个字符。