创建将匹配字符串中的要求的正则表达式

时间:2019-01-08 16:04:42

标签: php regex expression

问题

我需要用结构{A / B}编写一个符合以下要求的正则表达式。

要求/条件:

  • A和B只能是[UGWRB]之一。
  • 未显示U或G的结构无效。
  • 两个字符相等的结构无效。
  • U或G必须至少出现一次。
  • 该结构可以重复或连续无限次,只要单独读取以下每个实例仍然有效即可。 (请参阅下面的有效匹配项)

有效匹配项:

  • {U / G} {U / G} {U / G}
  • {W / G} {U / B}
  • {U / G} {U / B}
  • {U / G}
  • {G / U}
  • {U / B}
  • ...

无效的匹配项:

  • {U / U} {U / U}
  • {U / U} {G / G}
  • {U / G} {U / U}
  • {U / G} {R / B}
  • {G / G}
  • {R / B}
  • {W / R}
  • {黑白}
  • ...

我的尝试

到目前为止,这是我得到的,但是在所有UGWRB组合中,我只获得了14场比赛中的8场。

{([UG])(?(1)|\w)\/(?(1)\w|[UG])}

2 个答案:

答案 0 :(得分:1)

您必须使用正面和负面的前瞻才能完成任务:

^(?:{(?=[^{}]*[UG])([UGWRB])\/(?!\1)(?1)})+$

请参见live demo here

请注意,应设置m标志。

正则表达式细目:

  • ^匹配输入字符串的开头
  • (?:非捕获组的开始
    • {从字面上匹配{
    • (?=开始积极向前
      • [^{}]*[UG]组合查找[UG]
    • )前瞻结束
    • ([UGWRB])匹配并捕获字符类中的字母
    • \/(?!\1)(?1)匹配/,看下一个字符是否与最近捕获的字符不同
    • }从字面上匹配}
  • )+组结束,至少重复一次
  • $匹配输入字符串的结尾

答案 1 :(得分:1)

尝试此正则表达式:

^(?!.*{([UGWRB])\/\1})(?:{(?(?=[UG]).\/[UGWRB]|[WRB]\/[UG])})+$

Click for Demo

说明:

  • ^-匹配字符串的开头
  • (?!.*{([UGWRB])\/\1})-前瞻性否定,以确保类似{G/G}{U/U}{R/R}的结构在字符串的任何位置都不存在
  • {-匹配{
  • (?(?=[UG]).\/[UGWRB]|[WRB]\/[UG])-Regex Conditional。如果当前位置后跟UG,则匹配该字符,后跟/和字符类[UGWRB]。否则,匹配字符类[WRB],后跟/,后跟UG
  • }-匹配}
  • +-匹配1次以上的上述子序列(?:{(?(?=[UG]).\/[UGWRB]|[WRB]\/[UG])})
  • $-匹配字符串的结尾