表达式反向解析_正则表达式——反向引用

作者:施懿民

分组不仅用在匹配结果中,也可以在匹配的正则表达式中使用分组匹配的结果,这种功能称为反向引用(Backreference)。当待匹配的字符串中有些子字符串出现多次的话,正则表达式模式可以将第一个出现的子字符串保存在分组中,在模式的后面可以直接引用第一个匹配的结果。因为分组即可通过索引也可以通过名字来访问,所以反向引用里也有索引版和名字的版本:

根据索引反向引用的语法为:“umber”,number是分组在正则表达式中的位置,从1开始计数。如代码清单 3 - 8中第9行的模式“(w+)s(1)”,1即表示反向引用第一个分组“(w+)”的匹配结果,由于在后面的第13行需要将“1”当作一个新的分组使用 – match.Groups[2],所以使用括号将模式创建了一个新分组,否则的话括号是可以省略的。

在正则表达式里,“1”到”9”永远被解析成索引反向引用语法,如果使用的分组索引不存在,会导致正则表达式引擎抛出ArgumentException异常,如“(w+)s2”就会导致异常,因为“2”前面只有一个分组“(w+)”。“10”及以上只有在分组数足够的话才会被当作索引反向引用,否则会被当作普通的八进制数字进行匹配,不过也不建议读者在写太复杂的正则表达式,造成调试和代码阅读上的困难。

在Visual Studio Code等编辑器里同样是支持反向引用的,图 3 - 7中使用模式“(d+)(-)12“成功匹配“2009-09-09”这个字符串,而不能匹配“2018-12-31”,这是因为”1”对应的是第一个分组:“(d+)”,”2”对应的是第二个分组“(-)”。

3ac4bf02115cac86dc79807c8d7f6f1c.png

图 3 - 7在VS Code里使用反向引用

如果给分组命名过的话,使用命名反向引用就方便得多,命名反向引用的语法可以是:“k”或“k'name'”,其中name就是分组的名字。代码清单 3 - 8中第10行就演示这种使用方法,首先定义了一个“”分组用来匹配一个单词,再使用“k”反向引用前面匹配的结果,从而找出重复的单词。

替换

正则表达式除了可以用来在输入字符串中匹配和提取子字符串以外,还可以用在字符串替换中,在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}*(?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中的正则表达式替换模式说明

1126a33a3bf3b5c6073ce301a25091aa.png

在Visual StudioIDE和Visual Studio Code等文本编辑器中,也可以直接使用替换模式来提高编辑效率,如笔者经常将Excel、网页等地方拷贝的文字列表转换成源代码中的字符串数组,就会用到替换模式技巧。如图 3 - 8中,在查找文本框中使用“^(.+)$”模式来匹配每一行的完整字符串,在替换文本框中,模式"$&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值