【问题标题】:regex pattern to match alternating subpatterns正则表达式模式以匹配交替的子模式
【发布时间】:2011-04-01 22:14:55
【问题描述】:

我正在尝试设计一个正则表达式模式(在 PHP 中),它允许两个子模式的任何交替。因此,如果模式 A 匹配一组三个字母,而 B 匹配一组 2 个数字,那么所有这些都可以:

啊啊啊 aaa66bbb 66 67abc 12abc34def56ghi78jkl

我不介意哪个子模式开始或结束序列,只是在第一次匹配之后,子模式必须交替。我完全被这件事难住了 - 任何建议都将不胜感激!

【问题讨论】:

  • abc12def34ghi56jkl78mno 怎么样?他们应该匹配吗?
  • 或者aaa11bbb22,就此而言?
  • 是的,当然。抱歉,我没说清楚。每次模式 A 或 B 匹配时,它们可能是不同的字符串 - 唯一重要的是它们必须交替。所以abc12def34ghiaaa11bbb22 都是有效匹配项。

标签: php regex pcre


【解决方案1】:

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

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

这是一个简单的替换 - 三个字母或两个数字 - 但负前瞻确保相同的替代不会连续匹配两次。这是一个稍微优雅的 PHP 解决方案:

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

您可以将它们放入捕获组并使用(?1)(?2) 等在您想要的任何其他位置再次应用它们,而不是多次键入相同的子模式——在这种情况下,在前瞻中。

【讨论】:

  • 我也喜欢这个选项 - 类似于 cHao 的回答,但也许更时尚一点?谢谢艾伦。
【解决方案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:模式匹配“一组三个字母”和“一组两个数字”,这正是OP所说的。
  • 是的,但这些例子表明了一个更具体的群体
  • 例子是examples。它们不是唯一可能的模式,并且没有给出不应该匹配的示例。
  • 我认为这是完美的。很抱歉造成混淆 - 我已经改进了上面的示例。您应该了解,最终的模式 A 和 B 比 ([a-zA-Z]{3})(\d\d) 复杂得多。然而,cHao 所描述的插值正是我最终计划要做的。我只是无法理解模式交替的语法。
【解决方案3】:
/\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 次相同的数字组成。

此正则表达式将匹配

啊啊啊 11 bbb22 33cc ddd44ddd 55eee55 fff66fff66 77ggg77ggg

但不是

aaa11bbb

【讨论】:

  • 这不允许“两个子模式的任何交替”。当要求的是更通用的解决方案时,它只会匹配示例子模式。
  • 我会说这是解释问题!
  • 哦,现在是“解释问题”!当你对我投反对票时,这并不是那么主观......
  • 很抱歉,也许它有点快,但是根据给出的例子,我很确定他不想要混合字符或数字。所以我相信你错了。我们甚至现在!
  • 我不够清楚。我已经编辑了我的原始帖子:aaa11bbb 是有效匹配,所以恐怕 cHao 是正确的。但是怪我!
【解决方案4】:

查看this(并查看conditional subpatterns)。我个人从未使用过它们,但似乎正是您想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多