1、正则表达式正则表达式语言元素字符转义多数重要的正则表达式语言运算符都是非转义的单个字符。转义符 (单个反斜杠)通知正则表达式分析器反斜杠后面的字符不是运算符。例如,分析器将星号 (*) 视为重复限定符,而将后跟星号的反斜杠 (*) 视为 Unicode 字符 002A。下表中列出的字符转义在正则表达式和替换模式中都会被识别。转义符 说明 一般字符除 .$ ( | ) * + ? 外,其他字符与自身匹配。a 与响铃(警报)u0007 匹配。b 如果在 字符类中,则与退格符 u0008 匹配;如果不是这种情况,请参见本表后面的“注意”部分。t 与 Tab 符 u0009 匹配。r 与回车符 u00
2、0D 匹配。v 与垂直 Tab 符 u000B 匹配。f 与换页符 u000C 匹配。n 与换行符 u000A 匹配。e 与 Esc 符 u001B 匹配。040 将 ASCII 字符匹配为八进制数(最多三位);如果没有前导零的数字只有一位数或者与捕获组号相对应,则该数字为后向引用。(有关更多信息,请参见反向引用。)例如,字符 040 表示空格。x20 使用十六进制表示形式(恰好两位)与 ASCII 字符匹配。cC 与 ASCII 控制字符匹配;例如,cC 为 Ctrl-C。u0020 使用十六进制表示形式(恰好四位)与 Unicode 字符匹配。注意.NET Framework 不支持用于指
3、定 Unicode 的 Perl 5 字符转义。Perl 5 字符转义的格式是 x#,其中“#”是十六进制数字的序列。应改为使用本行中描述的 .NET Framework 字符转义。 在后面带有不识别为转义符的字符时,与该字符匹配。例如,* 与 x2A 相同。注意转义字符 b 是一个特例。在正则表达式中,b 表示单词边界(在 w 和 W 之间),不过,在 字符类中,b 表示退格符。在替换模式中,b 始终表示退格符。替换只在替换模式中允许替换。对于正则表达式中的类似功能,使用后向引用(如 1)。有关后向引用的详细信息,请参见反向引用和后向引用构造。字符转义和替换是在替换模式中识别的唯一的特殊构造
4、。下面几部分描述的所有语法构造只允许出现在正则表达式中;替换模式中不识别它们。例如,替换模式 a*$txtb 会插入字符串“a*”,该字符串后跟按 txt 捕获组匹配的子字符串,该子字符串后跟字符串“b”(如果有)。在替换模式中,* 字符不会识别为元字符。与此类似,在正则表达式匹配模式中不识别 $ 模式。在正则表达式中,$ 指定字符串的结尾。下表显示如何定义命名并编号的替换模式。字符 说明 $ 数字 替换按组号 number(十进制)匹配的最后一个子字符串。$ name 替换由 (? ) 组匹配的最后一个子字符串。$ 替换单个“$”字符。$& 替换完全匹配本身的一个副本。$ 替换匹配前的输入字
5、符串的所有文本。$ 替换匹配后的输入字符串的所有文本。$+ 替换最后捕获的组。$_ 替换整个输入字符串。字符类字符类是一个字符集,如果字符集中的任何一个字符有匹配,它就会找到该匹配项。下表总结了字符匹配语法。字符类 说明 . 匹配除 n 以外的任何字符。如果已用 Singleline 选项做过修改,则句点字符可与任何字符匹配。有关更多信息,请参见正则表达式选项。 aeiou 与指定字符集中包含的任何单个字符匹配。 aeiou 与不在指定字符集中的任何单个字符匹配。0-9a-fA-F 使用连字号 () 允许指定连续字符范围。p name 与 name 指定的命名字符类中的任何字符都匹配。支持的名
6、称为 Unicode 组和块范围。例如,Ll、Nd、Z、IsGreek、IsBoxDrawing。P name 与在 name 中指定的组和块范围不包括的文本匹配。w 与任何单词字符匹配。等效于 Unicode 字符类别 pLlpLupLtpLopNdpPcpLm。如果用 ECMAScript 选项指定了符合 ECMAScript 的行为,则 w 等效于 a-zA-Z_0-9。W 与任何非单词字符匹配。等效于 Unicode 字符类别 pLlpLupLtpLopNdpPcpLm。如果用 ECMAScript 选项指定了符合 ECMAScript 的行为,则 W 等效于 a-zA-Z_0-9。s
7、 与任何空白字符匹配。等效于 Unicode 字符类别 fnrtvx85pZ。如果用 ECMAScript 选项指定了符合 ECMAScript 的行为,则 s 等效于 fnrtv。S 与任何非空白字符匹配。等效于 Unicode 字符类别 fnrtvx85pZ。如果用 ECMAScript 选项指定了符合 ECMAScript 的行为,则 S 等效于 fnrtv。d 与任何十进制数字匹配。对于 Unicode 类别的 ECMAScript 行为,等效于 pNd,对于非 Unicode 类别的 ECMAScript 行为,等效于 0-9。D 与任何非数字匹配。对于 Unicode 类别的 EC
8、MAScript 行为,等效于 PNd,对于非 Unicode 类别的 ECMAScript 行为,等效于 0-9。可以使用 GetUnicodeCategory 方法找到某个字符所属的 Unicode 类别。有关 Unicode 字符类别的更多信息,请参见文档“Unicode Data File Format”(Unicode 数据文件格式),此文档可从 Unicode 技术委员会 (UTC) 的网站 http:/www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values 获得。正则表达式选项可以使用影响匹配行为的选项修改正
9、则表达式模式。可以通过下列两种基本方法之一设置正则表达式选项:可以在 Regex (pattern, options) 构造函数中的 options 参数中指定,其中 options 是 RegexOptions 枚举值的按位“或”组合;也可以使用内联 (?imnsx-imnsx:) 分组构造或 (?imnsx-imnsx) 其他构造在正则表达式模式内设置它们。在内联选项构造中,一个选项或一组选项前面的减号 (-) 用于关闭这些选项。例如,内联构造 (?ix-ms) 将打开 IgnoreCase 和 IgnorePatternWhiteSpace 选项而关闭 Multiline 和 Singl
10、eline 选项。默认情况下,关闭所有正则表达式选项。下表列出了 RegexOptions 枚举的成员以及等效的内联选项字符。请注意,选项 RightToLeft 和 Compiled 只适用于表达式整体而不允许内联。(它们只能在 Regex 构造函数的 options 参数中指定。)选项 None 和 ECMAScript 不允许内联。RegexOption 成员 内联字符 说明 None N/A 指定不设置任何选项。IgnoreCase i 指定不区分大小写的匹配。Multiline m 指定多行模式。更改 和 $ 的含义,以使它们分别与任何行的开头和结尾匹配,而不只是与整个字符串的开头和
11、结尾匹配。ExplicitCapture n 指定唯一有效的捕获是显式命名或编号的 (?) 形式的组。这允许圆括号充当非捕获组,从而避免了由 (?:) 导致的语法上的笨拙。Compiled N/A 指定正则表达式将被编译为程序集。生成该正则表达式的 Microsoft 中间语言 (MSIL) 代码;以较长的启动时间为代价,得到更快的执行速度。Singleline s 指定单行模式。更改句点字符 (.) 的含义,以使它与每个字符(而不是除 n 之外的所有字符)匹配。IgnorePatternWhitespace x 指定从模式中排除非转义空白并启用数字符号 (#) 后面的注释。(有关转义空白字符
12、的列表,请参见字符转义。)请注意,空白永远不会从字符类中消除。RightToLeft N/A 指定搜索是从右向左而不是从左向右进行的。具有此选项的正则表达式将移动到起始位置的左边而不是右边。(因此,起始位置应指定为字符串的结尾而不是开头。)为了避免构造具有无限循环的正则表达式的可能性,此选项不能在中流指定。但是,(? ) 将匹配的子字符串捕获到一个组名称或编号名称中。用于 name 的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如 (?name)。(? ) 平衡组定义。删除先前定义的 name2 组的定义并在 name1 组中存储先前定义的 name2 组和当前
13、组之间的间隔。如果未定义 name2 组,则匹配将回溯。由于删除 name2 的最后一个定义会显示 name2 的先前定义,因此该构造允许将 name2 组的捕获堆栈用作计数器以跟踪嵌套构造(如括号)。在此构造中,name1 是可选的。可以使用单引号替代尖括号,例如 (?name1-name2)。(?: ) 非捕获组。(? imnsx-imnsx : )应用或禁用子表达式中指定的选项。例如,(?i-s: ) 将打开不区分大小写并禁用单行模式。有关更多信息,请参见正则表达式选项。(?= ) 零宽度正预测先行断言。仅当子表达式在此位置的右侧匹配时才继续匹配。例如,w+(?=d) 与后跟数字的单词匹
14、配,而不与该数字匹配。此构造不会回溯。(?! ) 零宽度负预测先行断言。仅当子表达式不在此位置的右侧匹配时才继续匹配。例如,b(?!un)w+b 与不以 un 开头的单词匹配。(? ) 非回溯子表达式(也称为“贪婪”子表达式)。该子表达式仅完全匹配一次,然后就不会逐段参与回溯了。(也就是说,该子表达式仅与可由该子表达式单独匹配的字符串匹配。)命名捕获根据左括号的从左到右的顺序按顺序编号(与非命名捕获类似),但在对所有非命名捕获进行计数之后才开始对命名捕获进行编号。例如,模式 (?abc)/d+)?(?xyz)(.*) 按编号和名称产生下列捕获组。(编号为 0 的第一个捕获总是指整个模式)。编号
15、 名称 模式 0 0(默认名称) (?abc)/d+)?(?xyz)(.*) 1 1(默认名称) (?abc)/d+) 2 2(默认名称) (.*) 3 1 (?abc) 4 2 (?xyz) 后向引用构造下表列出了用于将后向引用修饰符添加到正则表达式中的可选参数。后向引用构造 定义 数字 后向引用。例如,(w)1 查找双写的单词字符。k 命名后向引用。例如,(?w)k 查找双写的单词字符。表达式 (?w)43 执行同样的操作。可以使用单引号替代尖括号,例如 kchar。请注意八进制转义代码和使用相同表示法的 number 后向引用之间的多义性。有关正则表达式引擎如何解析多义性的详细信息,请参
16、见反向引用。替换构造下表列出了用于修改正则表达式以允许进行二者之一/或匹配的特殊字符。替换构造 定义 | 与以 |(竖线)字符分隔的术语中的任何一项匹配;例如, cat|dog|tiger。使用最左侧的成功匹配。(?( 表达式 )yes|no) 如果表达式在此位置匹配,则与“yes”部分匹配;否则,与“no”部分匹配。“no”部分可省略。表达式可以是任何有效的子表达式,但它将变为零宽度断言,因此该语法等效于 (?(?=expression)yes|no)。请注意,如果表达式是命名组的名称或捕获组编号,则替换构造将解释为捕获测试(在本表的下一行对此进行了描述)。若要避免在这些情况下产生混淆,则可
17、以显式拼出内部 (?=expression)。(?( name )yes|no) 如果命名捕获字符串有匹配,则与“yes”部分匹配;否则,与“no”部分匹配。“no”部分可省略。如果给定的名称不与此表达式中使用的捕获组的名称或编号对应,则替换构造将解释为表达式测试(在本表的上一行进行了描述)。反向引用反向引用提供查找重复字符组的方便的方法。它们可被认为是再次匹配同一个字符串的快捷指令。例如,若要查找重复且相邻的字符(如单词“tall”中的两个 L) ,可以使用正则表达式 (?w)k,该正则表达式使用元字符 w 来查找任何单个单词的字符。分组构造 (? ) 将元字符括在其中,以强制正则表达式引擎
18、记住子表达式匹配(在此示例中将是任意单个字符) ,并以名称“char”保存它。反向引用构造 k 使引擎对当前字符和以名称“char”存储的先前匹配字符进行比较。只要单个字符与其前面的字符相同,整个正则表达式就可以找到一个匹配。要找到重复的全字,您可以修改该分组子表达式,以搜索前面是空格的任何字符组,而不是只搜索任意单个字符。可以用匹配任何字符组的子表达式 w+ 替换元字符 w,并使用元字符 s 匹配字符分组前的空格。这就生成了正则表达式 (?sw+)k,该正则表达式查找任何重复的全字(例如“the the”) ,但也会匹配指定字符串的其他重复情况,例如词组“the theory”中的重复情况。
19、为验证上述第二种匹配是以单词为边界的,可以将元字符 b 添加到重复匹配的后面。所生成的正则表达式 (?sw+)kb 只查找重复的、前面有空格的全字。分析反向引用表达式 1 到 9 总是指反向引用,而不是八进制代码。多位表达式 11 和更高位表达式在具有与该号码对应的反向引用时被视作反向引用;否则,它们会被解释为八进制代码(除非起始位是 8 或 9,在这种情况下它们被视为原义的“8”和“9” ) 。如果正则表达式包含对未定义的组成员的反向引用,则它被视作分析错误。如果有多义性问题,可以使用 k 表示法,该表示法是明确的,并且不会与八进制符号代码混淆;同样,诸如 xdd 等的十六进制代码也是明确的,并且不会与反向引用混淆。当 ECMAScript 选项标志被启用时,反向引用行为将稍有不同。有关更多信息,请参见 ECMAScript 与规范化匹配行为。匹配反向引用反向引用引用组的最近的定义(当从左到右匹配时,最靠近左侧的定义) 。具体地讲,就是当组建立多个捕获时,反向引用引用最近的捕获。例如,(?a)(?1b)* 使