группировка перед положительным взглядом сзади не соответствует

StackOverflow https://stackoverflow.com/questions/1805305

  •  05-07-2019
  •  | 
  •  

Вопрос

Возьмите следующий код:

$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 и каждого P внутри $ target (таким образом, PREG_OFFSET_CAPTURE).Шаблон работает для Ps, но он не соответствует ни одной из именованных групп "RuleName" или "funcName".

Что я упускаю из виду?

Спасибо.

Это было полезно?

Решение

Я думаю, что нашел причину.

  1. Ваши именованные обратные ссылки необязательны.
  2. Если они совпадают (а с первой попытки это так и есть), то движок регулярных выражений находится слева от "LPAREN".
  3. Следующий маркер, которому механизм регулярных выражений пытается сопоставить, - это символ пробела.Это происходит потому, что выражение lookbehind (?<=LPAREN) не использует символы в строке.
  4. Это не может соответствовать пробелу, потому что там есть буква "Л".
  5. Механизм регулярных выражений отбрасывает необязательные совпадения из 2.и продолжается до тех пор, пока не найдет следующее место.
  6. Он совпадает и продолжает совпадать с тех пор, захватывая все Ps.Но от названных групп пришлось отказаться, чтобы это сработало.

Я не уверен, зачем вам нужен взгляд сзади.Как насчет

/(?P<ruleName>NAME )?(?P<funcName>FUNC )?(?:LPAREN )(?:(?P<arg1>P))|(?P<args>P)(?=(?: RPAREN)|(?: COMMA))/
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top