使用正则表达式查找两个字符串之间的多个匹配项

Posted

技术标签:

【中文标题】使用正则表达式查找两个字符串之间的多个匹配项【英文标题】: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 你是个魔术师!非常感谢。请发送您的评论作为答案,以便我将其标记为答案。 【参考方案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。

以上是关于使用正则表达式查找两个字符串之间的多个匹配项的主要内容,如果未能解决你的问题,请参考以下文章

C# 正则表达式 - 为括号内的单个模式查找一个或多个匹配项

IntelliJ IDEA 查找两个字符之间任意内容正则表达式

通过Python中的正则表达式优化在两个列表之间查找匹配子字符串

Python - 使用正则表达式查找多个匹配项并将它们打印出来[重复]

C正则表达式,匹配两个字符串之间的内容

javascript正则表达式匹配两个字符串之间的所有内容(没有换行符)[重复]