请使用以下代码:

$target = 'NAME FUNC LPAREN P COMMA P COMMA P RPAREN';
//$target = 'NAME FUNC LPAREN P RPAREN';
//$target = 'NAME FUNC LPAREN RPAREN';
$pattern = '/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:(?<=LPAREN)(?: (?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA)))/';

preg_match_all($pattern,$target,$matches,PREG_OFFSET_CAPTURE|PREG_PATTERN_ORDER);

我需要在$ target中获得NAME,FUNC和每个P的位置(因此PREG_OFFSET_CAPTURE)。该模式适用于Ps,但它不匹配任何一个命名组<!> quot; ruleName <!> quot;或<!> quot; funcName <!> quot;。

我错过了什么?

感谢。

有帮助吗?

解决方案

我想我找到了原因。

  1. 您的指定反向引用是可选的。
  2. 如果匹配(并在第一次尝试时),则正则表达式引擎位于<!>“LPAREN <!>”的左侧。
  3. 正则表达式引擎尝试匹配的下一个标记是空格字符。这是因为lookbehind表达式(?<=LPAREN)不会消耗字符串中的字符。
  4. 因为有L
  5. 所以无法匹配空间
  6. 正则表达式引擎从2中丢弃可选匹配项,然后继续,直到找到下一个空格。
  7. 从那时起匹配并保持匹配,捕获所有P s。但是必须放弃指定的群体才能发挥作用。
  8. 我不确定你为什么需要这个后卫。 <怎么样

    /(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
    
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top