【问题标题】:Using regex to find multiple matches between two strings使用正则表达式查找两个字符串之间的多个匹配项
【发布时间】:2020-11-26 19:37:41
【问题描述】:

想象一下我有一个这样的字符串:

c x c x A c x c x c B c x c x

我想找到介于“A”和“B”之间的任何“c”字符。所以在这个例子中我需要得到 3 个匹配项。

我知道我可以使用lookahead 和lookbehind 标记。所以我使用了这个正则表达式:

(?<=A).*c.*(?=B)

但它得到了 A 和 B 之间的所有刺痛:c x c x c 作为一个结果。

如果我删除 .* 部分,则根本没有匹配项。

我做了一个example here。这样你就可以看到结果了。

【问题讨论】:

  • 例如(?:\G(?!^)|A)[^AB]*?\Kc(?=.*?B),见regex101.com/r/TeHHiF/1。如果AB 是多字符字符串的占位符,请使用(?:\G(?!^)|A)(?:(?!A).)*?\Kc(?=.*?B) (demo)
  • 哇! @WiktorStribizew 你是个魔术师!非常感谢。请发送您的评论作为答案,以便我将其标记为答案。

标签: regex pcre between


【解决方案1】:

这里有两种常见的情况:1) AB不同 单个字符串,2) AB不同 多字符串。

场景 1

你可以使用否定字符类:

(?:\G(?!^)|A)[^AB]*?\Kc(?=[^AB]*B)

this regex demo。详情:

  • (?:\G(?!^)|A) - A 或上一次成功匹配结束
  • [^AB]*? - 除AB 之外的任何零个或多个字符,尽可能少
  • \K - 匹配重置操作符,丢弃目前在整个内存匹配缓冲区中匹配的所有文本
  • c - c 字符/字符串
  • (?=[^AB]*B) - 后面必须跟零个或多个字符,而不是 AB,然后紧跟当前位置右侧的 B 字符。

场景 2

如果 AB 是多字符字符串的占位符,例如,ABCBCE 并且 c 是一些类似 c\d+ 的模式(匹配 c 和后面的一个或多个数字它)使用

(?s)(?:\G(?!^)|ABC)(?:(?!ABC).)*?\Kc\d+(?=.*?BCE)

this regex demo。详情:

  • (?s) - 一个 DOTALL 修饰符,使正则表达式引擎匹配任何带有 . 的字符
  • (?:\G(?!^)|ABC) - ABC 或上一次成功匹配结束
  • (?:(?!ABC).)*? - 任何不启动 ABC 字符序列的字符,0 次或更多次
  • \K - 匹配重置运算符
  • c\d+ - c 和一位或多位数字
  • (?=.*?BCE) - 任何零个或多个字符,尽可能少,后跟BCE

【讨论】:

  • 优秀的解决方案!看来我们可以使用简单的.*? 而不是(?:(?!ABC).)*?,因为我们不关心第一个ABCc 之间的其他可能的ABC
  • 这很棒。非常感谢你。但是有一个小缺陷。如果字符串是 c x c x ABC c1 x c2 x c3 BCE c4 x c5 x BCEc4c5 也将出现在结果中。我将(?:(?!ABC).)*? 部分更改为(?:(?!BCE).)*? 并解决了问题。但是仍然会有另一个问题,如果我们有这个字符串:ABC c0 x ABC c1 x c2 x c3 BCE c4 x c5 x BCEc0 也会出现在结果中。这个我想不通。
  • @MohsenHaeri 将两个定界符添加到回火前瞻中,(?s)(?:\G(?!^)|ABC)(?:(?!ABC|BCE).)*?\Kc\d+(?=(?:(?!ABC).)*BCE)。见this regex demo
猜你喜欢
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 2018-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
相关资源
最近更新 更多