Продолжение в конце предыдущего матча в RegEx (PCRE) - PullRequest
3 голосов
/ 01 января 2011

Я пытаюсь предотвратить привязку \ G якоря к началу строки.Я хочу, чтобы он совпадал только в конце последнего совпадения с регулярным выражением.

Учитывая следующий текст:

Pig, Cow, Goat
fruit: apple, orange, peach, pear
vegetable: Carrot, Lettuce, Cellery

И этот шаблон:

(fruit:|\G)([\w]+|[\, ])

Я хочуэто только для совпадения слов после "Fruit:", но мне нужно, чтобы захватить каждое слово в отдельности.Если бы я просто поставил + в самом конце этого шаблона, он бы совпал со всеми словами после «fruit:», но он бы захватил только «грушу», так как каждая итерация + останавливает на последнем.

Вотэта проблема.Этот шаблон работает, за исключением того, что он также соответствует «Свинья, Корова и Коза», потому что \ G будет соответствовать концу последнего соответствия ИЛИ началу всей строки.Как я могу предотвратить совпадение начала всей строки?

Я использую PCRE в PHP и использую Rubular.com, чтобы помочь мне выполнить быстрые тесты.

1 Ответ

6 голосов
/ 01 января 2011

На мой взгляд, вы regex не дали вам то, что вы сказали, что вы хотели. Вы сказали, что хотите, чтобы каждое слово следовало за «фруктами». Учитывая ваш пример, я не думаю, что ваша первая попытка действительно дала вам это. Попробуйте:

(?:fruit:\s*|\G,\s*)(\w+)

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

Вот краткое изложение:

  • (?: - запустить группу без захвата
  • fruit:\s* - преамбула для хорошего матча
  • | - или
  • \G,\s*) - позиция последнего совпадения, запятая и ноль или более пробелов
  • (\w+) захватить один или несколько символов слова

EDIT:

Чтобы предотвратить случай, когда вы получите совпадение в первой строке, если первая строка начинается с запятой, за которой следует одно или несколько слов, разделенных запятыми, просто добавьте отрицательный просмотр нулевой ширины на начальном якоре до \G:

(?:fruit:\s*|(?<!^)\G,\s*)(\w+)
...