写点什么

正则表达式 - 子表达式 & 回溯引用

  • 2024-04-02
    北京
  • 本文字数:2004 字

    阅读完需:约 7 分钟

正则表达式-子表达式&回溯引用

概念介绍

之前做底稿项目时,该项目主要将 ai 抽取的文本、表格数据通过正则表达式匹配进行处理,当时用到了正则的以下知识点


  1. 匹配单个字符

  2. 匹配一组字符

  3. 使用元字符

  4. 重复匹配

  5. 位置匹配等等,今天我在处理另外一个需求时,学习到了子表达式的使用。先说他能帮我解决什么事情,将目标匹配的内容进行分组,当成一个整体来进行应用。应用方面:

  6. 取值-取不同子表达式的值

  7. 替换-将不同的子表达式匹配的内容整体替换

上手使用:

语法:() 括号内就是正则表达式的其他元素了比如我要匹配某个 ip 地址,平常我们会这样写:


\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
复制代码


{n,m} m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次 {n,m}


匹配如下内容:


127.0.0.1192.168.10.1
复制代码


使用子表达式可以怎么做呢?观察上面的正则这个部分 \d{1,3}\.出现了多次,所以我们的正则可以改写为:


(\d{1,3}\.){3}\d{1,3}
复制代码


这样就很简单,将一个很长的正则表达式,可读性更好些。但是这并不是最终的正则。


最终的表达式,好的表达式并不是可以匹配到我们需要的数据,还要屏蔽掉我们不需要的数据


(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))
复制代码


[]数据范围{}前面字符或者元字符出现的次数| 是 或 的含义

应用

取值

既然是一个整体,我们怎么获取一个整体的值呢?比如我们想在一个文本中,把邮箱名称取出来。我们之前的思路就是先匹配出邮箱,然后程序取出来按照 @拆分。实际上正则可以一次帮我们做了这一件事情


\w+[\.\w]*@[\.\w]+\.\w+
复制代码


公司董事会确认,公司没有根据《上海证券交易所股票上市规则》等有关规定应披露而未披露的事项或与该等事项有关的筹划、商谈、意向、协议等。董事会也未获悉根据《上海证券交易所股票上市规则》等有关规定应披露而未披露的、对公司股票交易价格可能产生较大影响的信息。公司前期披露的信息不存在需要更正、补充之处发表人Lzh.rz1997@163.com
复制代码


如果我们修改下正则,添加子表达式


(\w+[\.\w]*)@[\.\w]+\.\w+
复制代码


在程序中可以通过 group 方式进行取不同组的值,group(index), index 从 0 开始意味着匹配第一个表达式。代码中我们使用 group(0)就可以取到Lzh.rz1997

替换

我们可能会有这样的需求,匹配到后,对邮箱增加一个超链接。超链接为:


<a href= "mailto:张三 @163.com">发送张三 email</a>


之前我的做法是,先匹配到邮箱,然后取出来,最后替换到文本中去。现在使用正则可以一步搞定,通过 $取不同的组数,利用匹配子表达式取值的特性在 java 中是这样做的:


public class ReplaceExpTest {      private static  final String text = "公司董事会确认,公司没有根据《上海证券交易所股票上市规则》等有关规\n" +              "定应披露而未披露的事项或与该等事项有关的筹划、商谈、意向、协议等。董事\n" +              "会也未获悉根据《上海证券交易所股票上市规则》等有关规定应披露而未披露的、\n" +              "对公司股票交易价格可能产生较大影响的信息。公司前期披露的信息不存在需要\n" +              "更正、补充之处发表人Lzh.rz1997@163.com";      private static final String reg = "((\\w+[\\.\\w]*)@[\\.\\w]+\\.\\w+)";      public static void main(String[] args) {          Matcher matcher = Pattern.compile(reg).matcher(text);          // 尝试查找与该模式匹配的输入序列的下一个子序列。          showMatchGroup(matcher);          // 开始替换          Matcher matcher1 = Pattern.compile(reg).matcher(text);          if (matcher1.find()){              String strcha = matcher1.replaceAll("<A HREF=\"mailto:$1\">$2</A>");              System.out.println(strcha);          }      }  }
复制代码


输出的结果为:


公司董事会确认,公司没有根据《上海证券交易所股票上市规则》等有关规定应披露而未披露的事项或与该等事项有关的筹划、商谈、意向、协议等。董事会也未获悉根据《上海证券交易所股票上市规则》等有关规定应披露而未披露的、对公司股票交易价格可能产生较大影响的信息。公司前期披露的信息不存在需要更正、补充之处发表人<A HREF="mailto:Lzh.rz1997@163.com">Lzh.rz1997</A>
复制代码

参考:

https://weread.qq.com/web/reader/c6932c00718ff68ac6959c4k64232b60230642e92efb54c?

测试工具:

regex101: build, test, and debug regex

这个奇怪需求

给我一个格式不正确的 json,帮我修正,有的字段缺少中括号,需要补全中括号。json 如下:



data1 = '{"org_info": "中国银行", "fields": ["长期借款", "period": "年", "start_date": "20231018", "stop_date": "20231018"}'
data2 = '{"org_info": "中国银行", "fields": ["长期借款", "应付债券总额", "period": "年", "start_date": "20231018", "stop_date": "20231018"}'
复制代码


fields 缺少中括号,使用正则进行修复。

仓库

https://gitee.com/xiedi_148/su-service-parent.git

用户头像

还未添加个人签名 2021-01-10 加入

还未添加个人简介

评论

发布
暂无评论
正则表达式-子表达式&回溯引用_#正则表达式_追随月光的战士_InfoQ写作社区