一 特殊字符转义
在表达式中用到的一些元字符不再表示原来的字面意义,如果要匹配这些有特殊意义的元字符,必须使用“\”将这些字符转义为原义字符。需要进行转义的字符有“$”、“(”、“)”、“*”、“+”、“.”、“[”、“]”、“?”、“\”、“/”、“^”、“{”、“}”、“|”。
“\”的作用是将下一字符标记为特殊字符、原义字符、反向引用或八进制转义符,所以,要匹配字面意义的“\”,需要使用“\\”表示。
二 贪婪匹配与非贪婪匹配
默认情况下,正则表达式使用最长匹配原则,即贪婪匹配原则。
例如,要将“book”中匹配“bo?”的部分替换成“l”,替换后的结果是“lok”,而不是“look”;如果要将“book”中匹配“bo*”的部分替换成“l”,替换后的结果是“lk”,而不是“lok”或“look”。
编译器会使用一种贪婪匹配算法,也就是说会尽可能让一个单元包含更多的字符。
如果当字符“?”紧跟任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式变成使用最短匹配原则,即非贪婪匹配原则。
例如,在字符串“booook”中,“bo+?”只匹配“bo”部分,而“bo+”匹配“boooo”部分。
三 特殊字符
\n 此处的n是一个一位的八进制数(0~7)。
例如,如果\n前面至少有n个捕获子匹配,那么\n是反向引用,否则,匹配ASCII码值等于n的字符。
\nm此处的m和n都是一个一位的八进制数(0~7)。
例如,如果\nm前面至少有nm个捕获子表达式,那么nm是反向引用。
如果\nm前面至少有n个捕获,那么\n是反向引用,m是字面意义上的数字字符。
如果前面的条件皆不存在,\nm匹配ASCII码值等于八进制的nm的字符。
四 分组组合与反向引用符
分组组合符是将表达式中某部分内容组合起来的符号。
反向引用符则是用于匹配分组组合捕获到的内容的标识符。
1 分组组合
“(pattern)”将pattern部分组合成一个可以统一操作的组合项和子匹配,每个捕获的子匹配项按照出现的顺序存储在缓冲区中。
缓冲区编号从1开始,最多可以存储99个子匹配捕获的内容。存储在缓冲区中的子匹配捕获的内容,可以在编程语言中被检索,也可以在正则表达式中被反向引用。
若要匹配字面意义的括号字符“(”和“)”,在正则表达式中要分别使用“\(”和“\)”。
2 反向引用
“\num”匹配编号为num的缓冲区所保存的内容,num是标识特定缓冲区的一位或两位十进制正整数,这种方式称为子匹配的反向引用。反向引用能提供表示相同匹配项的能力。
3 非捕获匹配
“(?:pattern)”匹配pattern但不获取匹配结果,即这是一个非获取匹配,不进行存储供以后使用。
它是将pattern部分组合成一个可以统一操作的组合项,但不把这部分内容当作子匹配捕获,即pattern部分是一个非捕获匹配,匹配的内容不存储在缓冲区中供以后使用。
这对必须进行组合但又不想让组合的部分具有子匹配特点的情况很有用。
例如,要将“abc?”中的“abc”组合起来,但并不想将匹配的内容保存在缓冲区中,应该使用“(?:abc)?”,而不能使用“(abc)?”。
4 正向“预测先行”匹配
“(?=pattern)”称为正向“预测先行”匹配,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,即该匹配不需要获取供以后使用。在被搜索字符串的相应位置必须有pattern部分匹配的内容,但不作为匹配结果处理,更不会存储在捕获缓冲区中供以后使用。
例如,“Windows (?=NT|2000)”只与“Windows 2000”或“Windows NT”中的“Windows”匹配,而不与“Windows 2003”中的“Windows”匹配。
注意:该模式下匹配的结果只是“Windows”部分,而使用“Windows (?:NT|2000)”匹配的是整个“Windows 2000”或“Windows NT”。如果要将“NT”和“2000”前面的“Windows”替换成“Win”,需要使用“Windows (?=NT|2000)”,而不能使用“Windows (?:NT|2000)”,否则,整个“Windows 2000”或“Windows NT”将被替换成“Win”。
5 反向“预测先行”匹配
“(?!pattern)”称为反向“预测先行”匹配,在被搜索字符串的相应位置不能有pattern部分匹配的内容,此外,其功能与正向“预测先行”匹配一样。
例如,“Windows (?!NT|2000)”不与“Windows 2000”或“Windows NT”中的“Windows”匹配,而可以与“Windows 2003”中的“Windows”匹配。