我正在尝试设计一个正则表达式模式(在PHP中),它允许任意两个子模式的交替。因此,如果模式A匹配一组三个字母,而B匹配一组2个数字,那么所有这些都可以:
aaa aaa66bbb 66 67abc 12abc34def56ghi78jkl
我不介意哪个子模式开始或结束序列,只是在第一次匹配后,子模式必须交替。我完全被这个难过 - 任何建议都会感激不尽!
答案 0 :(得分: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)'。
注意,如果你想匹配一些相同的字母或数字,或者相同的字母或数字的实例,你需要做的反向引用的一些魔法 - 可能是命名的,因为任何带编号的反向引用将取决于你想要的那个之前(或者你想要的那个和你所在的那个之间)的捕获组的数量,但是如果子模式有括号,那么这个数字会变得复杂在他们中间。
答案 1 :(得分:2)
以下是一般解决方案:
^(?:[a-z]{3}(?![a-z]{3})|[0-9]{2}(?![0-9]{2}))+$
这是一个简单的替换 - 三个字母或两个数字 - 但负向前瞻确保相同的替代品永远不会连续两次匹配。这是针对PHP的稍微优雅的解决方案:
/^(?:([a-z]{3})(?!(?1))|([0-9]{2})(?!(?2)))+$/
不是多次输入相同的子模式,而是可以让他们捕获组并使用(?1)
,(?2)
等来再次将它们应用到您想要的任何地方 - 在这种情况下,在向前看符号。
答案 2 :(得分:0)
查看this(并查看conditional subpatterns)。我个人从未使用它们,但似乎是你正在寻找的。 p>
答案 3 :(得分: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/
这将匹配由两个交替组组成的任何模式,一组由相同char的3倍组成,另一组由相同数字的2倍组成。
此正则表达式将匹配
aaa 11 bbb22 33ccc ddd44ddd 55eee55 fff66fff66 77ggg77ggg
但不是
aaa11bbb