1. 正则表达式
正则表达式:一种匹配文本中的字符序列的字符模式。在很多文本编辑器或其他工具里,正则表达式通常被用来检索或替换那些符合某种模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。
一个正则表达式就是由普通字符(例如字符 ‘a’ 到 ‘z’)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
1.1 元字符
字符 | 描述 | 实例 |
\d | 匹配任意的数字 | \d\d可以匹配12,但不匹配a1或1a等 |
\D | 匹配任意的非数字字符 | \D\D匹配a@,不匹配12 |
\w | 匹配单词字符(包括字母、数字、下划线和汉字) | |
\W | 匹配任意的非单词字符(包括字母、数字、下划线和汉字) | \W匹配@等,不匹配a |
\s | 匹配任何空白字符,包括空格、制表符、换行符等 | |
\S | 匹配任意非空白字符 | |
. | 匹配除换行符之外的任意字符 |
^ | 匹配行的开始位置 | "^The":表示所有以"The"开始的字符串("There","The cat"等) |
$ | 匹配行的结束位置 | "of despair$":表示以"of despair"结尾的字符串 |
\b | 匹配单词的开始或结束位置 | "\bcat"将匹配 "cat cat cat"首尾的"cat",中间的"cat"不会被匹配上 |
\B | \b的补集 | "\bcat"将匹配 "cat cat cat"中间的"cat" |
2. 字符类
在正则表达式中,元字符通常一次只能匹配一个位置或字符集合中的一个字符,但是如果要匹配的字符集合没有与之相对应的元字符时,则需要自定义匹配的字符集合。此时可以使用字符类解决这个问题。字符类是一个字符集合,如果该字符集合中的任何一个字符被匹配,则它就会找到该匹配项。
字符类是正则表达式中的“迷你”语言,可以在方括号" []"中定义。例如: [012345]匹配数字0,1,2,3,4,5中的任何一个。[Jj]ack匹配字符串“Jack”或者“jack”。
然而,正则表达式[0123456789]的书写非常不方便。因此,正则表达式引入连接符“-”定义字符的范围。例如:正则表达式[0-9]等价于正则表达式[0123456789]。
3. 限定符
正则表达式的元字符一次只能匹配一个位置或一个字符,如果要匹配零个、一个或多个字符时,则需要使用限定符。限定符用于指定允许特定字符或字符集自身重复出现的次数。常用限定符的说明如表2.11所示。
字符 | 描述 | 实例 |
{n} | 重复n次 | 'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 。 |
{n,} | 至少重复n次 | 'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | 重复至少n次,最多m次 | "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。 |
+ | 重复至少1次,等同{1,} | 'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
* | 重复至少0次,等同{0,} | zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。 |
? | 当该字符紧跟在任何一个其他限定符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。 | 对于字符串"oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。 |
4. 转义字符
正则表达式定义了一些特殊的元字符,如^、$、.等。由于这些字符在正则表达式中被解释成其他的特定的意义,如果需要匹配这些字符,则需要使用转义字符来解决这一问题。转义字符为“\”(反斜杠),它可以取消这些字符(如^、$、.等)在表达式中具有的特殊意义,转义字符说明及实例如表2.12。
字符 | 描述 | 实例 |
\ | 有些字符被用来表示特殊的含义,但是要匹配其本身时就需要用转义字符。 | "\\"匹配"\" "\."匹配"." "\*"匹配"*" "\+"匹配"+" "\unnnn"匹配一个4位16进制数指定的Unicode |
5. 分组、“或”、以及反向引用
前面讲到怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复一个字符串就应该使用分组。
分组又称为子表达式,即把一个正则表达式的全部或部分分成一个或多个组。其中,分组使用括号“()”表示。分组之后,可以将括号“()”之中的表达式看成一个整体来处理,然后再指定这个子表达式的重复次数。例如:“(\d{1,3}\.){3}\d{1,3}”是一个简单的IP地址匹配表达式。 “(\d{1,3}\.){3}”匹配三位数字加上一个英文句号重复3次,“\d{1,3}”匹配1到3位的数字。
“或”使用字符“|”来表示。如果某一个字符串匹配了正则表达式中的字符“|”的左边或者右边的规则,那么该字符串也匹配了该正则表达式。例如:“0\d{2}-\d{8}|0\d{3}-\d{7}|0\d{3}-\d{8}”匹配当前国内部分地区的3种固定电话号码:一种是号码的前3位为区号,后8位为本地号码;另一种是号码的前四位为区号,后7位为本地号码;最后一种是号码的前4位为区号,后8位为本地号码。其中,区号和本地号码都使用连接符号“-”进行连接。
反向引用:当一个正则表达式被分组之后,每一个组将自动被赋予一个组号,该组号可以代表该组的表达式。其中,组号的编制规则为:从左到右,以分组的左括号“(”为标志,第一个分组组号为1,第二个分组的组号为2,以此类推。反向引用提供了查找重复字符组的方便方法。它可被认为是再次匹配同一个字符串的快捷指令。反向引用可以使用数字命名的组号,语法为:\number,也可以使用指定命名的组号,语法为:\k<name>。例如:表达式“('|")(.*?)(\1)”在匹配“'Hello',"World"”时,首先匹配到的内容是:“'Hello'”。再次匹配下一个时,可以匹配到“"World"”。
2. RegEX Tester用来测试正则表达式
regEX Tester是一个简单的用来测试正则表达式的工具,是开源的。