匹配交替子模式的正则表达式模式

3
我正在尝试设计一个正则表达式模式(在PHP中),它将允许两个子模式的任何交替。因此,如果模式A匹配三个字母的组合,而B匹配两个数字的组合,则所有这些都是可以的:
aaa
aaa66bbb
66
67abc
12abc34def56ghi78jkl
我不介意哪个子模式开始或结束序列,只要在第一次匹配后,子模式必须交替出现。我完全被卡住了 - 任何建议将不胜感激!

2
abc12def34ghi56jkl78mno怎么处理?它们应该匹配吗? - Alan Moore
还是aaa11bbb22呢? - cHao
是的,绝对没问题。抱歉,我的表达不够清晰。每次当模式A或B匹配时,它们可能是不同的字符串 - 唯一重要的是它们必须交替出现。因此abc12def34ghi或者aaa11bbb22都是有效的匹配。 - George Crawford
4个回答

3
以下是通用解决方案:

这里是一个通用解决方案:

^(?:[a-z]{3}(?![a-z]{3})|[0-9]{2}(?![0-9]{2}))+$

这是一个简单的替换——三个字母或两个数字——但负向预查确保相同的替代品不会连续匹配两次。以下是一个稍微更加优雅的 PHP 解决方案:

/^(?:([a-z]{3})(?!(?1))|([0-9]{2})(?!(?2)))+$/

不要多次输入相同的子模式,你可以将它们放入捕获组中,并使用(?1)(?2)等来在其他地方再次应用它们——在这种情况下,在前瞻中使用。


我也喜欢这个选项——类似于cHao的回答,但可能更加时尚?谢谢Alan。 - George Crawford

2
"/^(?:$A(?:$B$A)*$B?|$B(?:$A$B)*$A?)\$/"

将匹配模式A后跟任意数量的交替模式B和模式A,以及可能的最终B...或者B后跟任意数量的A-B对加上一个A(如果有)。

我已经将其作为字符串(并转义了最后的$),因为你需要进行一些插值。如果要使?匹配正确的内容,请确保$A和$B处于某种分组中(例如括号)。在您的示例中,$A可能是'([a-zA-Z]{3})',而$B可能是'(\d\d)'。

请注意,如果要匹配一些相同的字母或数字或相同的字母或数字集合的实例,您将需要使用反向引用来进行一些魔法--可能是命名引用,因为任何编号的反向引用都将取决于您想要的捕获组之前(或在您想要的捕获组与您所在位置之间)的捕获组数,但如果子模式中有括号,则该数字会变得复杂。


([a-zA-Z]{3}) 可匹配 'aXu'。而 (\d\d) 则可匹配 '10'。 - jigfox
@jigfox:这些模式匹配“三个字母一组”和“两个数字一组”,这正是OP所说的。 - cHao
是的,但这些示例表明了一个更具体的群体。 - jigfox
这些示例只是“示例”。它们不是唯一可能的模式,也没有给出任何不应匹配的示例。 - cHao
我觉得这很完美。抱歉造成混淆 - 我已经改进了上面的例子。你应该明白最终的模式A和B要比仅仅是 ([a-zA-Z]{3})(\d\d) 复杂得多。然而,cHao描述的插值正是我最终打算做的。我只是无法理解这些模式的交替语法。 - George Crawford

0
/\b(?:(([a-z])\2\2)(?:(([0-9])\4)\1)*(?:([0-9])\5)?|(([0-9])\7)(?:(([a-z])\9\9)\6)*(?:([a-z])\10\10)?)\b/

或者如果你想在三个字符的组中允许任何非数字字符:

/\b(?:((\D)\2\2)(?:((\d)\4)\1)*(?:(\d)\5)?|((\d)\7)(?:((\D)\9\9)\6)*(?:(\D)\10\10)?)\b/

这将匹配任何由两个交替组成的模式,其中一个组由3次相同字符组成,另一个组由2次相同数字组成。

这个正则表达式将匹配

aaa
11
bbb22
33ccc
ddd44ddd
55eee55
fff66fff66
77ggg77ggg

但不会匹配

aaa11bbb

这不允许“任何两个子模式的交替”。它只会匹配示例子模式,而要求更一般的解决方案。 - cHao
我会说这是解释的问题! - jigfox
哦,现在变成了“解释的问题”!当你给我点踩的时候,它并不是那么主观。 - cHao
很抱歉,也许我说得有点快,但是根据所给的例子,我非常确定他不想要混合字符或数字。所以我认为你错了。我们现在扯平了! - jigfox
我表达不够清楚。我已经编辑了原始帖子:“aaa11bbb”是一个有效的匹配,所以cHao是正确的,恐怕是我的错! - George Crawford

0

看一下this(并检查条件子模式)。我个人从未使用过它们,但似乎是你正在寻找的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接