0

采取以下代码:

$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,但它与命名组“ruleName”或“funcName”中的任何一个都不匹配。

我错过了什么?

谢谢。

4

1 回答 1

1

我想我找到了原因。

  1. 您命名的反向引用是可选的。
  2. 如果它们匹配(并且在第一次尝试时匹配),则正则表达式引擎位于“LPAREN”的左侧。
  3. 正则表达式引擎尝试匹配的下一个标记是空格字符。这是因为lookbehind 表达式(?<=LPAREN)不使用字符串中的字符。
  4. 它无法匹配空间,因为有一个 L
  5. 正则表达式引擎丢弃 2. 中的可选匹配项,然后继续运行,直到找到下一个空格。
  6. 它匹配并从那时起继续匹配,捕获所有Ps。但是必须放弃命名组才能使其正常工作。

我不确定你为什么需要向后看。怎么样

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
于 2009-11-26T19:58:23.477 回答