1、对特殊字符进行转义
在介绍其他元字符的用法之前,我们认为应该先把特殊字符的转义问题向大家解释清楚。
元字符是一些在正则表达式里有着特殊含义的字符。英文句号(.)是一个元字符,它可以用来匹配任何一个单个字符。类似地,左方括号([)也是一个元字符,它标志着一个字符集合的开始。
因为元字符在正则表达式里有着特殊的含义,所以这些字符就无法用来代表它们本身。比如说,你不能使用一个[来匹配[本身,也不能使用.来匹配.本身。来看一个例子,我们打算用一个正则表达式去匹配一个包含着[和]字符的javascript数组:
文本:
var myarray = new array();
...
if (myarray[0] == 0) {
...
}
正则表达式:
myarray[0]
结果:

在这个例子里,原始文本是一段javascript代码,正则表达式则是程序员在使用一个文本编辑器去编写javascript代码时经常会用到的搜索字符串。我们的本意是用这个正则表达式把代码里的myarray[0]记号找出来,可结果与预期完全不一样。为什么会这样?因为[和]在正则表达式里是用来定义一个字符集合(而不是[和]本身)的元字符,所以,myarray[0]将匹配myarray后面跟着一个该集合成员的情况,而那个集合只有一个成员0。因此,myarray[0]只能匹配到myarray0。
在元字符的前面加上一个反斜杠就可以对它进行转义——转义序列\.将匹配.本身,转义序列[将匹配[本身。每个元字符都可以通过给它加上有个反斜杠前缀的办法来转义,如此得到的转义序列将匹配那个字符本身而不是它特殊的元字符含义。要想匹配[和],就必须对这两个字符进行转义。下面的例子与刚才的问题完全一样,但我们这次对正则表达式里的元字符都进行了转义:
正则表达式:
myarray\[0\]
结果:

这次搜索取得了预期的结果。\[将匹配[, \]将匹配],所以myarray[0]匹配到了myarray[0]。
具体到这个例子,用一个正则表达式来进行搜索多少有点儿小题大做——因为一个简单的文本匹配操作已足以完成这一任务,而且还会更容易一些。但如果你想查找的不仅仅是myarray[0],还包括了myarray[1]、myarray[2]等,用一个正则表达式来进行搜索就很有必要了。具体做法是,对[和]进行转义,再列出需要在它们之间得到匹配的字符。如果你想匹配数组元素0到9,你构造出来的正则表达式应该是下面这个样子:
myarray\[[0-9]\]
任何一个元字符都可以通过给它加上一个反斜杠字符(\)作为前缀的办法来转义,能够被转义的元字符并不仅局限于我们这里提到的那几个。
配对的元字符(比如[或])不用作元字符时必须被转义,否则正则表达式分析器很可能会抛出一个错误。
对元字符进行转义需要用到\字符。这意味着\字符也是一个元字符——它的特殊含义是对其他元字符进行转义。在需要匹配\本身的时候,我们必须把它转义为\。
看看下面这个简单的例子。例子中的原始文本是一个包含着反斜杠字符的文件路径(用于dos和windows系统),而我们想在一个linux或unix系统上使用这个路径——也就是说,我们需要把这个路径里的反斜杠字符(\)全部替换为正斜杠字符(/):
文本:
\home\ben\sales\
正则表达式:
\\
结果:

\匹配\,总共找到了4个匹配。如果你在这个正则表达式里只写出了一个\的话,你应该会看到一条出错消息。这是因为正则表达式分析器会认为你的正则表达式不完整,在一个完整的正则表达式里,字符\的后面永远跟着另一个字符。
2、匹配空白字符
元字符大致可以分为两种:一种是用来匹配文本的(比如.),另一种是正则表达式的语法所要求的(比如[和])。随着学习的深入,你将发现越来越多的这两种元字符,而我们现在要介绍给大家的是一些用来匹配各种空白字符的元字符。
在进行正则表达式搜索的时候,我们经常会遇到需要对原始文本里的非打印空白字符进行匹配的情况。比如说,我们可能需要把所有的制表符找出来,或者我们需要把换行符找出来,这类字符很难被直接输入到一个正则表达式里,但我们可以使用下表列出的特殊元字符来输入它们。

我们来看一个例子。例子中的原始文本包含着一些以逗号分隔(csv格式)的数据记录,而我们的任务是在对这些记录做进一步处理之前,先把夹杂在这些数据里的空白行去掉。我们是这么做的:
文本:
"101","ben","forta" "102","jim","james" "103","roberta","robertson" "104","bob","bobson"
正则表达式:
\r\n\r\n
结果:

\r\n匹配一个“回车+换行”组合,有许多操作系统(比如windows)都把这个组合用作文本行的结束标签。使用正则表达式\r\n\r\n进行的搜索将匹配两个连续的行尾标签,而那正是两条记录之间的空白行。
\r\n是windows所使用的文本行结束标签。unix和linux系统只使用一个换行符来结束一个文本行;换句话说,在unix/linux系统上匹配空白行只使用\n\n即可,不需要加上\r。同时适用于windows和unix/linux系统的正则表达式应该包含一个可选的\r和一个必须被匹配的\n。你可以在下一章看到一个这样的例子。
一般来说,需要匹配\r、\n和\t(制表符)等空白字符的情况比较多见,需要匹配其他空白字符的情况要相对少一些。
3、匹配特定的字符类别
到目前为止,你已经见过如何匹配特定的字符、如何匹配任意单个字符(用.)、如何匹配多个字符中的某一个(用[和])以及如何进行取非匹配(用^)。字符集合(匹配多个字符中的某一个)是最常见的匹配形式,而一些常用的字符集合可以用特殊元字符来代替。这些元字符匹配的是某一类别的字符(术语称之为“字符类”)。类元字符并不是必不可少的东西(你总是可以通过逐一列举有关字符或是通过定义一个字符区间的办法来匹配某一类字符),但用它们构造出来的正则表达式简明易懂,在实践中很有用。
3.1、匹配数字(与非数字)
[0-9]是[0123456789]的简写形式,它可以用来匹配任何一个数字。如果你想匹配的是除数字以外的其他东西,那么把这个集合“反”过来写成[^0-9]就行了。下表列出了用来匹配数字和非数字的类元字符。

为了演示这些元字符的用法,我们来看一个在前面见过的例子:
文本:
var myarray = new array();
...
if (myarray[0] == 0) {
...
}
正则表达式:
myarray\[\d\]
结果:

[匹配[, \d匹配任意单个数字字符,]匹配],所以myarray[\d]匹配出myarray[0]。myarray[\d]是myarray[[0-9]]的简写形式,而后者又是myarray[[0123456789]]的简写形式。这个正则表达式还可以匹配myarray[1]、myarray[2],等等(但不匹配myarray[10])。
正如大家看到的那样,在与正则表达式打交道的时候,同样的问题几乎总是有好几种不同的解决办法。这些办法并无优劣之分,你尽可以选择最熟悉的那种语法。
正则表达式的语法是区分字母大小写的。\d匹配数字,\d与\d的含义刚好相反。接下来将看到的其他类元字符也是如此。
3.2、匹配字母和数字(与非字母和数字)
字母和数字——a到z(不分大小写)、数字0到9、再加上下划线字符(_)——是另一种比较常用的字符集合;这些字符常见于各种名字里,如(文件名、子目录名、变量名、数据库对象名,等等)。下表列出了用来匹配字母数字和非字母数字的类元字符。

下面这个例子里的原始文本是一些来自某个数据库的记录,那些记录的内容是美国和加拿大某些城市的邮政编码:
文本:
11213 a1c2e3 48075 48237 m1b4f2 90046 h1h2h2
正则表达式:
\w\d\w\d\w\d
结果:

在这个模式里,交替出现的\w和\d元字符将使得匹配结果里只包含加拿大城市的邮政编码。
在上面这个例子里,我们使用的正则表达式解决了我们的问题。但它正确吗?请大家思考一下,为什么美国的邮政编码没有被匹配出来?是因为它们只由数字构成、还是因为什么其他原因?
我们将不给出这个问题的答案,理由很简单——例子里的模式解决了问题。这里的关键是正则表达式很少有对错之分(当然,前提是它们能解决问题),我们更关心的是它们的复杂程度——而这要由模式匹配操作的精确程度来决定;如果你需要更精确的匹配,就需要构造更复杂的正则表达式。
3.3、匹配空白字符(与非空白字符)
另一种常见的字符类别是空白字符。在前面的内容里,我们向大家介绍了一些用来匹配某个特定的空白字符的元字符。下表列出了用来匹配所有空白字符的类元字符。

用来匹配退格字符的[\b]元字符是一个特例:它不在类元字符\s的覆盖范围内,当然也就没有被排除在类元字符\s的覆盖范围外。
3.4、匹配十六进制或八进制数值
你或许不会遇到需要通过某个特定字符的十六进制值或八进制值来匹配它的情况,但我们希望大家明白这是可以做到的。
3.4.1、使用十六进制值
在正则表达式里,十六进制(逢16进1)数值要用前缀\x来给出。比如说,\x0a对应于ascii字符10(换行符),其效果等价于\n。
3.4.2、使用八进制值
在正则表达式里,八进制(逢8进1)数值要用前缀\0来给出,数值本身可以是两位或三位数字。比如说,\011对应于ascii字符9(制表符),其效果等价于\t。
有不少正则表达式实现还允许使用\c前缀来指定各种控制字符。比如说,\cz将匹配ctrl-z。不过,在实际工作中,必须使用这种语法的情况相当少见。
4、使用posix字符类
对元字符以及各种字符集合进行的讨论,必须要提到posix字符类。posix字符类是许多(但不是所有)正则表达式实现都支持的一种简写形式。
javascript不支持在正则表达式里使用posix字符类。
posix语法与我们此前见过的元字符不太一样。为了演示posix字符类的用法,我们来看一个前一章里的例子——利用正则表达式从一段html代码里把rgb值查找出来:
文本:
<body bgcolor="#336633" text="#ffffff"
marginwidth="0" marginheight="0"
topmargin="0" leftmargin="0">
正则表达式:
#[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]
结果:

在前一章里使用的模式是重复写出的6个[0-9a-fz-f]字符集合,把那6个[0-9a-fz-f]全部替换为[[:xdigit:]]就得到这里的模式。它们的匹配结果完全一样。
这里使用的模式以[[开头、以]]结束(两对方括号)。这是使用posix字符类所必须的。posix字符类必须括在[:和:]之间,我们使用的posix字符类是[:xdigit:](不是:xdigit:)。外层的[和]字符用来定义一个字符集合,内层的[和]字符是posix字符类本身的组成部分。
一般来说,支持posix标准的正则表达式实现都支持下表所列出的那12个posix字符类,但在一些细节方面可能会与这里的描述有细微的差异。

到此这篇关于正则表达式使用元字符(必知必会)的文章就介绍到这了,更多相关正则表达式使用元字符内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论