正则表达式条件预测,下一个捕获组与PCRE匹配

时间:2018-01-24 21:16:01

标签: php regex conditional pcre capture-group

我搜索了答案,但我没有发现任何相关信息。 希望你能帮助我解决我的问题。

所以我尝试使用基于字符串末尾的捕获组的lookahead条件搜索字符串。 这意味着如果最后的捕获组是匹配的,那么使条件组与某些东西匹配,如果最后的捕获组不匹配,那么就是其他东西。

See my regex in use here

(?:((?(?=ls)yes|no))\${(?:(?P<type>VAR)\s+)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\s*\=\s*(\$\{CALL\s+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s*\}|\"[^\"]*\"|'[^']*'|[0-9]*|(?:[fF]alse|[tT]rue))\s*\}(?<ls>[^\s]{1}))

输入:

    ${VAR foo="What"}x

    ${VAR foo="What"} 

    yes${VAR foo="What"}

    no${VAR foo="What"}x

正如你所看到的,它捕获了“没有”这个词。如果最后有什么东西不是,但它没有捕捉到“是”的字样。如果没什么。

1 个答案:

答案 0 :(得分:1)

您的模式包含(?(?=ls)yes|no),它实际上是在寻找角色ls。我已经改变了你的模式,以便利用DEFINE构造来实现子模式的可重用性。据我所知,PCRE没有办法检查条件后是否定义了一个组。这可以使用平衡组在中完成,但PCRE不使用这些方法。 PCRE确实具有(?(name)yes|no)(?(1)yes|no)条件,但它不适用于前向引用(比较在测试变量之前是否存在变量)。

See regex in use here

(?(DEFINE)
  (?# var )
  (?<var>[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*)
  (?# val )
  (?<val>(?&call)|(?&str)|(?&num)|(?&bool))
  (?<call>\$\{CALL\s+[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*\s*\})
  (?<str>"[^"]*"|'[^']*')
  (?<num>\d+)
  (?<bool>(?i)(?:false|true)(?-i))
)
((?(?=yes\${VAR\s+(?&var)\s*\=\s*(?&val)\s*\}\s)yes|no))
\${(?P<type>VAR)\s+((?&var))\s*\=\s*((?&val))\s*\}(\S)?

如果不在正向前瞻中复制子模式,则可以使用以下(as seen in use here)。令牌(?8)递归第8个捕获组:

(?(DEFINE)
  (?# var )
  (?<var>[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*)
  (?# val )
  (?<val>(?&call)|(?&str)|(?&num)|(?&bool))
  (?<call>\$\{CALL\s+[a-zA-Z_\x7f-\xff][\w\x7f-\xff]*\s*\})
  (?<str>"[^"]*"|'[^']*')
  (?<num>\d+)
  (?<bool>(?i)(?:false|true)(?-i))
)
((?(?=no(?8)\S)no|yes))
(\${(?P<type>VAR)\s+((?&var))\s*\=\s*((?&val))\s*\})(\S)?