匹配规则

image.png

分组捕获

一般正则表达式只能替换匹配的部分, 不能指定替换匹配部分中的需要替换的部分. 分组捕获可以处理这个问题
分组捕获, 可将一个字符串分割成数份, 只替换需要替换的部分

  1. class UnitTest {
  2. @Test
  3. fun test() {
  4. var content = "abc <img alt width=\"10\" height=\"100\" style=\"width: 200px; height: 20px\" src='https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg\" id=\"xx\" class=\"class\"/> def"
  5. var regex = "(.*)(<img\\s)(.*)(src=[\"'].*?[\"'])(.*)(/>)(.*)"
  6. var pattern = Pattern.compile(regex)
  7. var matcher = pattern.matcher(content)
  8. if (matcher.matches()) {
  9. var sb = StringBuffer()
  10. for (i in 1..matcher.groupCount()) {
  11. println(">>>>>> matcher.group($i): " + matcher.group(i))
  12. if (i != 3 && i != 5) {
  13. sb.append(matcher.group(i))
  14. }
  15. }
  16. println(">>>>>> result: $sb")
  17. }
  18. }
  19. }

输出结果:

  1. >>>>>> matcher.group(1): abc
  2. >>>>>> matcher.group(2): <img
  3. >>>>>> matcher.group(3): alt width="10" height="100" style="width: 200px; height: 20px"
  4. >>>>>> matcher.group(4): src='https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg"
  5. >>>>>> matcher.group(5): id="xx" class="class"
  6. >>>>>> matcher.group(6): />
  7. >>>>>> matcher.group(7): def
  8. >>>>>> result: abc <img src='https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg"/> def

贪婪匹配/非贪婪匹配

举个例子,假设有以下这段html字符,我想拿到a标签中的内容:

  1. <a>南京长江大桥</a>哈哈<a>南京市长江大桥</a>

然后我写了这样一个正则:<a>(.)*</a>
在线测试的结果如下:

  1. <a>南京长江大桥</a>哈哈<a>南京市长江大桥</a>

这个结果与我们的预期不符,正常我应该得到两个匹配的结果才对,但是现在却只匹配到一个结果。
现在把刚刚的正则改成这样:<a>(.)*?</a>
在线测试的结果如下:

  1. <a>南京长江大桥</a>
  2. <a>南京市长江大桥</a>

说的是正则在不约束的情况下会继续自动向右进行匹配,直到匹配结束,只要匹配的数据与正则的最后一个值匹配就算是匹配到了。
不贪 说的是只要匹配到就结束,不继续向右进行匹配了。
问号 ? 就解决了贪婪的问题,使得问号前面的字符匹配到之后就结束,但是并不是把 ? 放在哪里都可以解决贪婪的,在正则里,有一些属于贪婪模式量词,比如以下这些:

  1. {m,n}
  2. {m,}
  3. ?
  4. *
  5. +

代码示例

  1. @Test
  2. fun test1() {
  3. var content = "abc <img alt width=\"10\" height=\"100\" style=\"width: 200px; height: 20px\" src='https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg\" id=\"xx\" class=\"class\"/> def"
  4. // 贪婪匹配
  5. // 贪婪匹配会匹配到目标最后出现的位置
  6. var regex = "(.*)(<img.*:)(.*)"
  7. // 非贪婪匹配
  8. // 非贪婪匹配会匹配到目标首次出现的位置
  9. var regex = "(.*)(<img.*?:)(.*)"
  10. var pattern = Pattern.compile(regex)
  11. var matcher = pattern.matcher(content)
  12. if (matcher.matches()) {
  13. for (i in 1..matcher.groupCount()) {
  14. println(">>>>>> matcher.group($i): " + matcher.group(i))
  15. }
  16. }
  17. }
  1. // 贪婪匹配
  2. >>>>>> matcher.group(1): abc
  3. >>>>>> matcher.group(2): <img alt width="10" height="100" style="width: 200px; height: 20px" src='https:
  4. >>>>>> matcher.group(3): //dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg" id="xx" class="class"/> def
  5. // 非贪婪匹配
  6. >>>>>> matcher.group(1): abc
  7. >>>>>> matcher.group(2): <img alt width="10" height="100" style="width:
  8. >>>>>> matcher.group(3): 200px; height: 20px" src='https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2534506313,1688529724&fm=26&gp=0.jpg" id="xx" class="class"/> def

参考链接

在线正则表达式测试:

生成正则表达式图片: