zoukankan      html  css  js  c++  java
  • 如何写出一个符合要求的正则

    如果你正在苦恼如何写一个正则的话,那么或许本文对你有所帮助
    文中的这个例子或许同个字符串截取同样可以做到,但本文仅尝试以纯正则的角度解决问题

    转载请注明出处 https://www.cnblogs.com/majianming/p/14590599.html

    首先看一下这个例子

    <br><br>D             >> -    MJ 1989<br>
    <br>D -    MJ 2000>><br>
    <br>D - 17.05.2011>> -    MJ 2013<br>
    <br><br>D -    MJ 2010>> - 01.11.2010<br>
    
    <br>D - 24.06.2002>> - 25.08.2002<br>
    <br><br><br><br><br><br>D -    MJ 2011>> -    MJ 2011<br>
    

    需求是获取br标签中的MJ 2000 或者 25.08.2002 这个字符串;在>> 这个左边的是开始日期,右边是结束日期,最后的结果需要给出开始年份和结束日期的字符串,并且如果任意一个日期为空,也需要提取出来,因为需要提取出的一个是开始日期还是结束日期


    在开始之前,我们假设一下我们最后可以的到的结果

    分组1为开始年份 比如MJ 2000 或者为空串

    分组2为开始年份 比如MJ 2013 或者为空串

    好的 我们现在以这个结果去找寻可能的解决方案


    首先我们可以观察得到这样的规律

    这个字符串以若干的<br>开头和结尾,并且在开头的<br>结束之后会有个D

    那么我们的开头为^<br>(这个地方先假设只有一个<br>),前文说到会有多个<br>,所以我们需要用量词来形容,并且我们需要形容的是整个<br> 所以需要用括号包裹起来,我们假设至少会有一个<br>

    所以我们的式子变为^(<br>)+`

    接下来匹配开头br 结束的D

    式子为^(<br>)+`

    同理可得结尾式子应该是(<br>)+$

    然后我们先把首尾衔接起来,中间使用.* 先匹配所有文字,同时使用分组包裹 即(.*)
    ^(<br>)+D(.*)(<br>)+$

    可以得到这样的匹配结果

    我们会发现实际上我们只是为了<br>这个标签用量词进行形容,我们并不关心他里面是什么值将需要从不分组上获取到的,但是现在我们

    现在可以从看到实际上我们将这个标签的值获取到了分组,并且占用了分组1的位置,导致我们的结果获取到了不必要的文本(如果可以接受分组1 并不是我们需要的结果 也可以忽略)

    所以我们使用非捕获组(?:)来包裹一个式子 用来表示这个我们只是想对整体进行一些操作,但是我们并不关心这个式子是什么内容

    所以我们的式子变成^(?:<br>)+D(.*)(?:<br>)+$

    我们也可以看到我们现在获取到了整个除了br的文本内容

    通过>>可以将文本内容分为开始时间和结束时间

    所以分两部分提取内容 式子为 ^(?:<br>)+D(.*)>>(.*)(?:<br>)+$

    可以看到每个匹配的项中都有且只有两个分组,并且分组中含有我们需要的日期

    那么我们接下来需要做的就是在这个文本中提起我们需要的部分

    先看左边

    有三种情况空的 、MJ 2000以及24.06.2002 三种情况 并且存在一些空格

    所以我们用(MJ d{4}) 和 (d{2}.d{2}.d{4}) 和 () 三个分组提取内容

    即()|(MJ d{4})|(MJ d{4})|(d{2}.d{2}.d{4})

    因为可能在日期之前存在空格或者横杠 所以我们用[- ]+来匹配

    接下来我们用[- ]*(()|(MJ d{4})|(MJ d{4})|(d{2}.d{2}.d{4})) 来替换第一个左边的.*

    得到^(?:<br>)+D([- ]*(()|(MJ d{4})|(d{2}.d{2}.d{4})))>>(.*)(?:<br>)+$

    发现实际上再一次因为组的关系我们捕获了整串左边的文本,所以我们再次使用非捕获组来修复这个问题

    ^(?:<br>)+D(?:[- ]*(()|(MJ d{4})|(d{2}.d{2}.d{4})))>>(.*)(?:<br>)+$

    我们又发现实际上分组1和分组2是相同的内容

    这个地方有两种处理方式

    第一种,将匹配每一种日期情况的分组去除或者改为非捕获组

    ^(?:<br>)+D(?:[- ]*(|MJ d{4}|d{2}.d{2}.d{4}))>>(.*)(?:<br>)+$

    ^(?:<br>)+D(?:[- ]*((?:)|(?:MJ d{4})|(?:d{2}.d{2}.d{4})))>>(.*)(?:<br>)+$

    第二种,将包裹所有日期可能的分组改为非捕获组(这个地方可以思考测试一下为什么不能把这个分组去除

    无论哪种情况 都可以得到这个结果

    同理将左边的表达替换到右边 就可以得到最后的结果

    ^(?:<br>)+D(?:[- ]*(|MJ d{4}|d{2}.d{2}.d{4}))>>(?:[- ]*(|MJ d{4}|d{2}.d{2}.d{4}))(?:<br>)+$

    即分组1 是开始日期 分组2是结束日期

    转载请注明出处 https://www.cnblogs.com/majianming/p/14590599.html

    使用到的工具网址
    https://regex101.com/

  • 相关阅读:
    Haproxy+Keepalived高可用环境部署梳理(主主和主从模式)
    使用nginx sticky实现基于cookie的负载均衡
    CENTOS 6.6初始化SHELL脚本
    Java 开源博客 Solo 1.2.0 发布
    Java 开源博客 Solo 1.2.0 发布
    Java多线程-synchronized关键字
    Maven项目pom.xml配置详解
    4.0 苹果系统安装之黑苹果(4)
    3.0 Windows和Linux双系统安装(3)
    2.0 Linux系统的安装之Fedora安装单系统(2)
  • 原文地址:https://www.cnblogs.com/majianming/p/14590599.html
Copyright © 2011-2022 走看看