zoukankan      html  css  js  c++  java
  • 从头学习正则-2如何用正则实现复杂的查找和替换

    假设我们现在要去查找 15 位或 18 位数字。根据前面学习的知识,使用量词可以表示出现次数,使用管道符号可以表示多个选择,你应该很快就能写出d{15}|d{18}。但经过测试,你会发现,这个正则并不能很好地完成任务,因为18位数字也会匹配上前15位,具体如下图所示。

    出现这个问题的原因,因为大多数正则实现中,多分支选择都是左边优先,所以如果把上面的表达式调换下顺序,就可以符合要求了

    另外如果把这个问题看成15个数字,后面的3个数字有或没有,可以用d{15}(d{3})?

    这里(d{3})我们使用了括号,如果不使用括号,你会发现有问题,括号在正则中的功能就是用于分组。简单来理解就是,由多个元字符组成某个部分,应该被看成一个整体的时候,可以用括号括起来表示一 个整体,这是括号的一个重要功能。其实用括号括起来还有另外一个作用,那就是“复用”。

    分组和编号

    括号在正则中可以用于分组,被括号括起来的部分“子表达式”会被保存成一个子组。 那分组和编号的规则是怎样的呢?其实很简单,用一句话来说就是,第几个括号就是第几个 分组。这么说可能不好理解,我们来举一个例子看一下。 这里有个时间格式 2020-05-10 20:23:05。假设我们想要使用正则提取出里面的日期和时间。

    我们可以写出如图所示的正则,将日期和时间都括号括起来。这个正则中一共有两个分组, 日期是第 1 个,时间是第 2 个。

    保存子组

    在括号里面的会保存成子组,但有些情况下,你可能只想用括号将某些部分看成一个整体, 后续不用再用它,类似这种情况,在实际使用时,是没必要保存子组的。这时我们可以在括 号里面使用 ?: 不保存子组。

    如果正则中出现了括号,那么我们就认为,这个子表达式在后续可能会再次被引用,所以不 保存子组可以提高正则的性能。除此之外呢,这么做还有一些好处,由于子组变少了,正则 性能会更好,在子组计数时也更不容易出错。

    那到底啥是不保存子组呢?我们可以理解成,括号只用于归组,把某个部分当成“单个元 素”,不分配编号,后面不会再进行这部分的引用。

    正则 示例
    保存子组 (xx) d{15}(d{3})?
    不保存子组 (?:xx) d{15}(?:d{3})?

    括号嵌套

    前面讲完了子组和编号,但有些情况会比较复杂,比如在括号嵌套的情况里,我们要看某个 括号里面的内容是第几个分组怎么办?不要担心,其实方法很简单,我们只需要数左括号 (开括号)是第几个,就可以确定是第几个子组。

    在阿里云简单日志系统中,我们可以使用正则来匹配一行日志的行首。假设时间格式是 2020-05-10 20:23:05 。

    日期分组编号是 1,时间分组编号是 5,年月日对应的分组编号分别是 2,3,4,时分秒的 分组编号分别是 6,7,8。

    分组引用

    在知道了分组引用的编号 (number)后,大部分情况下,我们就可以使用 “反斜扛 + 编 号”,即 umber 的方式来进行引用,而 JavaScript 中是通过编号来引用的,如1

    分组引用和查找

    介绍了子组和引用的基本知识,现在我们来看下在正则查找时如何使用分组引用。比如 我们要找重复出现的单词,我们使用正则可以很方便地使“前面出现的单词再次出现”,具 体要怎么操作呢?我们可以使用 w+ 来表示一个单词,针对刚刚的问题,我们就可以很容 易写出 (w+) 1或 (w+)s1这个正则表达式了。

    分组引用在替换中的使用

    和查找类似,我们可以使用反向引用,在得到的结果中,去拼出来我们想要的结果。还是使 用刚刚日期时间的例子,我们可以很方便地将它替换成, 2020 年 05 月 10 日这样的格 式。

    ![image-20210605105547998](/Users/chenbang/Library/Application Support/typora-user-images/image-20210605105547998.png)

    在文本编辑器中的使用

    用 Sublime Text 3 来当例子,给你讲解一下正则查找和替换的使用方式。 Sublime Text 3 是一个跨平台编辑器,非常小巧、强悍,虽然是一个收费软件,但可以永久试用,你自行可以下载安装。 当熟练使用编辑器之后,你会发现在很多工作里都可以使用它,不需要编写代码就可以完成。

    问题练习

    最后,我们来做一个小练习吧。有一篇英文文章,里面有一些单词连续出现了多次,我们认 为连续出现多次的单词应该是一次,比如:

    the little cat cat is in the hat hat hat, we like it.

    其中 cat 和 hat 连接出现多次,要求处理后结果是

    the little cat is in the hat, we like it.

  • 相关阅读:
    linux之sed用法【转载】
    关于Cookie和Session【转载】
    Oracle分页查询与RowNum
    fstream的用法
    Java:Date、Calendar、Timestamp的区别、相互转换与使用【转载】
    DatabaseMetaData的用法【转载】
    关于SQL的Group By
    【转载】B树、B-树、B+树、B*树都是什么
    Spring的MVC控制器返回ModelMap时,会跳转到什么页面?
    关于jsp中超链接的相对路径
  • 原文地址:https://www.cnblogs.com/bangaj/p/14852363.html
Copyright © 2011-2022 走看看