在正向回顾前面分组不匹配

发布于 2024-08-12 08:46:26 字数 548 浏览 2 评论 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);

我需要获取 NAME、FUNC 和 $target 中每个 P 的位置(即 PREG_OFFSET_CAPTURE)。该模式适用于 Ps,但它与命名组“ruleName”或“funcName”都不匹配。

我缺少什么?

谢谢。

Take the following code:

$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);

I need to get the position of NAME, FUNC and each P within the $target (thus PREG_OFFSET_CAPTURE). The pattern works for Ps, but it doesn't match either of the named groups "ruleName" or "funcName".

What am I missing?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

烂柯人 2024-08-19 08:46:26

我想我已经找到原因了。

  1. 您的命名反向引用是可选的。
  2. 如果它们匹配(并且在第一次尝试时就匹配),则正则表达式引擎位于“LPAREN”的左侧。
  3. 正则表达式引擎尝试匹配的下一个标记是空格字符。这是因为后向表达式 (?<=LPAREN) 不消耗字符串中的字符。
  4. 它无法匹配空格,因为有一个 L
  5. 正则表达式引擎丢弃 2. 中的可选匹配项,并继续下去,直到找到下一个空格。
  6. 从那时起它就会匹配并保持匹配,捕获所有 P。但要使之发挥作用,就必须放弃指定的群体。

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

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/

I think I've found the reason.

  1. Your named backreferences are optional.
  2. If they match (and on the first try they do), then the regex engine is standing to the left of "LPAREN".
  3. The next token the regex engine tries to match is a space character. This is because the lookbehind expression (?<=LPAREN) does not consume characters in the string.
  4. It can't match the space because there's an L
  5. The regex engine discards the optional matches from 2. and goes on until it finds the next space.
  6. It matches and keeps matching from then on, capturing all the Ps. But the named groups had to be given up for this to work.

I'm not sure why you need the lookbehind. How about

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文