【问题标题】:How to match only if a character occurs n times inside the match?仅当一个字符在匹配中出现 n 次时如何匹配?
【发布时间】:2019-02-04 12:10:25
【问题描述】:

https://regex101.com/r/gNNlKM/2

我想匹配 START:test:test:test:asd:xxx:yyy:zzz:12345:END,但前提是 : 出现 4 次或更多次。

一般来说,以下工作:(START.*?)\d+(:END) 但是我怎样才能让:{4,} 进入呢?

匹配的字符串可能会重复多次。喜欢:START:test:test:test:asd:xxx:yyy:zzz:12345:END...START:test:test:test:asd:xxx:yyy:zzz:12345:END... 重要的是 :{4,} 匹配只应用于每个 START-END 令牌内。

旁注:我在这里使用匹配组,因为我稍后想在这种特殊情况下删除数字。但这对于如何获得 n 次匹配的问题并不重要。

【问题讨论】:

  • 您似乎在寻找START 后跟4x :[^:]*,即: 后跟一些非: 字符,然后是:END

标签: java regex


【解决方案1】:

你可以这样写你的正则表达式,

(START(?:(?:(?!START)[^:])*:){3,})\d+(:END)

只有当 : 在字符串中恰好包含 4 次时才会匹配。

说明:

  • (START - 启动捕获组并匹配 START 字面意思
  • (?:(?:(?!START)[^:])*:){3,}) - 这匹配一些可选文本,如果看到文字 START 后跟 : 则拒绝匹配,其中 {3,} 表示三次或更多次。
  • \d+ - 匹配一位或多位数字
  • (:END) - 从字面上再匹配一个 :END 并在 group2 中捕获它

Demo

【讨论】:

  • 附带说明:(?:) 是一个非捕获组,不会匹配 :,在这种特定情况下可能会造成混淆
  • @Lino:OP 写了(:END) 而不是(?:END),所以这不是非捕获组。此外,如果您在他的 regex101 URL 中注意到,他将其引用为 $2 因此这不是 OP 的错字,而是打算在 group2 中捕获
  • 我说的是(?:[^:]*:),它以(?: 开头,所以它的行为类似于non-capturing-group
  • @Lino:这是故意的。我故意通过将?: 设置为非捕获组,因为 OP 在他的原始正则表达式中没有该组,我不想引入任何额外的组,因为 OP 已经有两个预期的组,他在他的回溯中引用解决方案。
  • 谢谢!还有一个问题:我修改了示例以便它可以重复,并且 {n} 匹配应该只在每个 STARTEND 标记之间单独计算。
猜你喜欢
  • 2016-06-01
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 2012-04-06
  • 1970-01-01
  • 2014-06-29
相关资源
最近更新 更多