【问题标题】:Regular Expression conditional lookahead with next capture group match PCRE正则表达式条件前瞻与下一个捕获组匹配 PCRE
【发布时间】:2018-01-24 21:16:00
【问题描述】:

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

所以我尝试基于字符串末尾的捕获组在具有先行条件的字符串之后进行搜索。 这意味着如果最后的捕获组匹配,则使条件组与某些东西匹配,如果最后的捕获组不匹配,则与其他东西匹配。

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

如你所见,如果结尾有东西,只要不是 \s,它就会捕获单词“no”,但如果它什么都没有,它不会捕获单词“yes”。

【问题讨论】:

  • (?(?=ls)yes|no) 从不匹配“是”。条件表示如果接下来的两个直接字符是ls,则匹配yes。不可能!

标签: php regex conditional pcre capture-group


【解决方案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)?

【讨论】:

  • 哇,感谢您的回答,我从中学到了很多东西(您向我展示了一些新事物和做某事的方法)。对我来说只是另一个问题,在 PHP 模式中可以像你一样在模式中创建新行(我的意思是它不应该在没有任何断线的情况下在一行中)?
  • 据我所知,PCRE 没有检查是否定义了组的方法请您解释一下吗?
  • @Almog 你的意思是模式中的空白?这是因为我添加了x 修饰符,它使正则表达式引擎忽略模式中的空白。尝试使模式更简洁时很有帮助
  • (?(name)... 命名参考条件(PCRE) ?
  • @revo 我已经更新了我的问题。我用你上面提出的条件玩了很多。它似乎不适用于前向引用。这可以在这里看到:Works with backreferences,但doesn't work with forward references。我对此可能错了,但我无法获得前向引用条件的工作示例。也许你可以详细说明?
猜你喜欢
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多