分组不仅用在匹配结果中,也可以在匹配的正则表达式中利用分组匹配的结果,这种功能称为反向引用(Backreference)。当待匹配的字符串中有些子字符串涌现多次的话,正则表达式模式可以将第一个涌现的子字符串保存在分组中,在模式的后面可以直接引用第一个匹配的结果。由于分组即可通过索引也可以通过名字来访问,以是反向引用里也有索引版和名字的版本:
根据索引反向引用的语法为:“\number”,number是分组在正则表达式中的位置,从1开始计数。如代码清单 3 - 8中第9行的模式“(\w+)\s()”,即表示反向引用第一个分组“(\w+)”的匹配结果,由于在后面的第13行须要将“”当作一个新的分组利用 – match.Groups[2],以是利用括号将模式创建了一个新分组,否则的话括号是可以省略的。
在正则表达式里,“”到””永久被解析成索引反向引用语法,如果利用的分组索引不存在,会导致正则表达式引擎抛出ArgumentException非常,如“(\w+)\s”就会导致非常,由于“”前面只有一个分组“(\w+)”。“”及以上只有在分组数足够的话才会被当作索引反向引用,否则会被当作普通的八进制数字进行匹配,不过也不建议读者在写太繁芜的正则表达式,造成调试和代码阅读上的困难。
在Visual Studio Code等编辑器里同样是支持反向引用的,图 3 - 7中利用模式“(\d+)(-)\1\2“成功匹配“2009-09-09”这个字符串,而不能匹配“2018-12-31”,这是由于”\1”对应的是第一个分组:“(\d+)”,”\2”对应的是第二个分组“(-)”。
图 3 - 7在VS Code里利用反向引用
如果给分组命名过的话,利用命名反向引用就方便得多,命名反向引用的语法可以是:“\k<name>”或“\k'name'”,个中name便是分组的名字。代码清单 3 - 8中第10行就演示这种利用方法,首先定义了一个“<dup>”分组用来匹配一个单词,再利用“\k<dup>”反向引用前面匹配的结果,从而找出重复的单词。
更换
正则表达式除了可以用来在输入字符串中匹配和提取子字符串以外,还可以用在字符串更换中,在Regex.Replace方法中可以利用更换(Substitution)模式来利用匹配结果进行更换操作,这个方法有一个replacement参数,在replacement参数中可以利用更换模式。更换模式以字符“$”开头,常日跟分组一起利用,与反向引用类似,支持按索引和按命名来利用分组匹配结果。如代码清单 3 - 14中,利用正则表达式将不同货币金额中的货币符号去掉,只留下金额的方法。在第1行的模式中:
l \p{Sc}:匹配货币符号字符,这个字符是可选的;
l (\s?\d+[.,]?\d):“\s?”匹配零到一个空格字符,“\d+[.,]?\d”匹配金额,金额的整数部分和小数部分利用点号“.”或逗号“,”分隔,不同国家表示小数的办法是不一样的,中国习气上利用点号“.”分隔小数,而西欧一些国家如德国的习气上利用逗号“,”分隔小数。当然这个模式有一个额外的匹配效果 – 即可以匹配按千分位表示的数字,如第4行中末了一个数字:“123,456.00”。
代码清单 3 - 14正则表达式更换模式示例
1 var pattern = @\公众\p{Sc}(\s?\d+[.,]?\d)\"大众;
2 var replacement = \"大众$1\公众;
3 var input = \公众$16.32 12.19 £16.29 €18.29 €18,29 ¥123.34 $123,456.00\公众;
4 var result = Regex.Replace(input, pattern, replacement);
5 Console.WriteLine(result);
6
7 pattern = @\"大众\p{Sc}(?<amount>\s?\d+[.,]?\d)\"大众;
8 replacement = \"大众${amount}\公众;
9 result = Regex.Replace(input, pattern, replacement);
10 Console.WriteLine(result);
如果模式成功匹配,第2行中的“$1”保存的是第一个分组匹配的结果,数字“1”是分组的索引,跟反向引用类似,正则表达式中的分组索引是从1开始的。第7行利用与第1行相同的模式,只不过命名匹配金额的分组为“amount”,因此在第8行的更换模式中可以直策应用名称“amount”来利用匹配结果。
表 3 - 5 .NET中的正则表达式更换模式解释
在Visual StudioIDE和Visual Studio Code等文本编辑器中,也可以直策应用更换模式来提高编辑效率,如笔者常常将Excel、网页等地方拷贝的笔墨列表转换成源代码中的字符串数组,就会用到更换模式技巧。如图 3 - 8中,在查找文本框中利用“^(.+)$”模式来匹配每一行的完全字符串,在更换文本框中,模式\"大众$&\"大众,则在每行文本的前后加上双引号,并在字符串的末端加上逗号“,”来符合字符串数组的定义语法,更换完成后,稍加改动就可以直接拷贝到源码中当作数组定义利用了。
图 3 - 8在文本编辑器中利用更换模式
(织码开门,打开技能学习的大门。)