首页 > 解决方案 > `,` 后的正则表达式捕获由 `AND` 分隔的所有文本

问题描述

考虑以下文本文件;

NETHERLANDS (THE)
BOLIVIA (PLURINATIONAL STATE OF)
COCOS (KEELING) ISLANDS (THE)
ANTIGUA AND BARBUDA

TEST1, SOME TEXT
TEST2, SAINT HELENA AND ASCENSION AND TRISTAN DA CUNHA
TEST3, BONAIRE AND SINT EUSTATIUS AND SABA

我正在尝试捕获第一个字符之后,的所有字符,并且可以选择用 分隔AND,所需的结果是:

No Match (no ,)
No Match (no ,)
No Match (no ,)
No Match (no ,)

SOME TEXT
SAINT HELENA - ASCENSION - TRISTAN DA CUNHA
BONAIRE - SINT EUSTATIUS - SABA

这篇文章为例,我创建了以下正则表达式:

/(?<= AND |\, )(.*)(?= AND |$)/mU

正则表达式101

这工作正常,你可以在这里看到,除了不包含,( ANTIGUA AND BARBUDA) 的情况


问题:如何更改此正则表达式,使其仅匹配包含至少一个的行,
我已经在网上搜索了一个解决方案,比如这个这个答案,不幸的是,我无法在不破坏积极的前瞻性的情况下添加这些修复。

标签: phpregex

解决方案


幸运的是它是 PCRE,您可以使用\G

(?>,|\G(?!\A) +AND) +\K(?>(?! +AND).)+

在此处查看现场演示

为了加快匹配过程,匹配^[^,]*之前,将有助于:

(?>^[^,]*,|\G(?!\A) +AND) +\K(?>(?! +AND).)+

解释

起初我们有两个选择:1) 匹配,或 2) \G(?!\A)\G(?!\A)意味着比赛应该从上一场比赛结束的地方继续。所以它应该总是匹配 a,在继续之前。

匹配后,,我们尝试匹配之前出现的任何其他内容AND。这是由这部分完成的:

 +\K(?>(?! +AND).)+
^ This is a space!

\K这里的元字符负责不包括到目前为止匹配的匹配项。换句话说,它是一个匹配重置器。由于您不需要任何早期出现的东西,我们使用\K将它们从输出中删除。

在一场完整的比赛之后,下一场比赛应该从第二次交替开始,即:

\G(?!\A) +AND

它寻找一个AND前面有空格的,然后我们又得到了我们想要的模式。


推荐阅读