【问题标题】:Overlapping matches in Regex - Scala正则表达式中的重叠匹配 - Scala
【发布时间】:2023-04-02 09:56:02
【问题描述】:

我正在尝试从遵循模式 XYX 的字符串中提取 3 个字母的所有可能组合。

val text = "abaca dedfd ghgig"
val p = """([a-z])(?!\1)[a-z]\1""".r
p.findAllIn(text).toArray

当我运行脚本时,我得到:

aba, ded, ghg

它应该是:

aba, aca, ded, dfd, ghg, gig

它不检测重叠的组合。

【问题讨论】:

标签: regex scala pattern-matching scala-2.12


【解决方案1】:

方法包括将整个模式包含在前瞻中以仅使用起始位置:

val p = """(?=(([a-z])(?!\2)[a-z]\2))""".r
p.findAllIn(text).matchData foreach {
   m => println(m.group(1))
}

前瞻只是对当前位置的断言(测试),其中的模式不消耗字符。您正在寻找的结果在第一个捕获组中(因为整个匹配都是空的,所以需要它来获取结果)。

【讨论】:

  • 就是这样,谢谢。它工作完美。正则表达式很棒,对我来说就像黑魔法。我仍然很难理解这个概念。当我尝试在 Sublime Text 搜索或 regexr.com 等工具中使用此模式时,它不起作用。所以我必须更好地理解这一点。 ps:我需要这个来帮助我解决代码出现的第 7 天。 adventofcode.com/2016/day/7
  • @oxcarh:你必须明白,前瞻断言只是一个测试,不消耗字符(换句话说,整个匹配总是一个空字符串)。它适用于 sublime 文本(我刚刚测试过),但在 regexr.com 上出现错误(这可能是错误的)。
【解决方案2】:

您需要捕获整个模式并将其放入积极的前瞻中。 Scala 中的代码如下:

object Main extends App {
    val text = "abaca dedfd ghgig"
    val p = """(?=(([a-z])(?!\2)[a-z]\2))""".r
    val allMatches = p.findAllMatchIn(text).map(_.group(1))
    println(allMatches.mkString(", "))
    // => aba, aca, ded, dfd, ghg, gig
}

online Scala demo

请注意,由于要检查的组的 ID = 2,并且组 1 将包含您需要收集的值,因此反向引用将变为 \2

【讨论】:

  • 我已经在 CH 的回答下阅读了您的 cmets,并且必须告诉您 regexr.com 仅支持纯 JS 正则表达式,而实际上没有针对已知限制提出 any 解决方法。这些限制之一是收集零宽度匹配的能力,即使它们包含非空捕获组。见Regexr.com shows my regex can match 0 characters, and therefore matches infinitely。要在那里使用它,只需在末尾添加一个./(?=(([a-z])(?!\2)[a-z]\2))./g
  • 如果您解释一下您需要在 Sublime Text 中使用字符串和正则表达式做什么,我可能会提供帮助。您要创建这些重叠文本的列表并删除周围的所有文本吗?
猜你喜欢
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 2013-04-05
  • 1970-01-01
相关资源
最近更新 更多