如何写出一个符合要求的正则
如果你正在苦恼如何写一个正则的话,那么或许本文对你有所帮助
文中的这个例子或许同个字符串截取同样可以做到,但本文仅尝试以纯正则的角度解决问题
转载请注明出处 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/