Разбор строки с помощью Regex - необязательные группы захвата - PullRequest
1 голос
/ 24 июня 2019

Я пытаюсь разобрать и токенизировать рецепты.Ингредиенты могут быть написаны двумя основными способами:

Стиль 1

1 Ripe Avocado

1x Ripe Avocado - x необязательно и иногда присутствует

ИЛИ:

Стиль 2

1 Ripe Avocado (lrg) 123

1x Ripe Avocado (lrg) 123 - если присутствует сокращение, то есть целое число кода элемента

Я пытаюсь а) определить, совпадает ли это со стилем 1 или 2 и б) , разбить на следующие группы захвата .

[1][Ripe Avocado][lrg]?[123]?

Кажется, я не могу последовательно разобрать это, поэтому любая помощь будет принята с благодарностью!

Редактировать:

^(\d+)x? ([a-zA-Z0-9_', -]+) - это то, что у меня было, но это не такt учитывать дополнительные группы захвата в стиле 2.

Ответы [ 2 ]

2 голосов
/ 24 июня 2019

Мне кажется, что Стиль 1 и Стиль 2 очень похожи. Я бы использовал это регулярное выражение для извлечения всех необходимых групп:

/(\d+).? ([\w ]*) ?(?>\((.*)\) (.*))?/

Затем вы можете определить, является ли это Стиль 1 или Стиль 2, на основании наличия соответствующих групп 3 и 4.

К вашему сведению, вы можете использовать очень полезное regex101 для проверки регулярных выражений: https://regex101.com/r/0LYxdc/1

Приветствия

Lucas

2 голосов
/ 24 июня 2019

Вы можете использовать шаблон с необязательной второй частью для сокращения и целого кода элемента.Значения, которые вы можете записать в группе захвата, дают вам 2 группы и 2 необязательные группы.

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

Предполагая, что это слова и их можно сопоставить, используя символы слова \w, вы можете использовать:

\b(\d+)x? (\w+(?: \w+)*)(?: \(([^()]+)\) (\d+))?\b

Пояснение

(с пробеломобозначается [ ] для ясности)

  • \b Граница слова
  • (\d+)x? Группа захвата 1, совпадение цифр 1+, затем сопоставление необязательно x
  • [ ](\w+(?: \w+)*) Совпадение с пробелом, затем захват в группе 2, соответствующие символам 1+ слова и повторение 0+ раз пробела и символов 1+ слов
  • (?: Группа без захвата
    • [ ]\( Соответствие пробелу и (
    • ([^()]+) захват группы 3, соответствие не () с использованием отрицательного класса символов
    • \) Соответствие )
    • Совпадение пробела и захват в группе 4, соответствующие 1+ цифрам
  • )? Закрыть группу без захвата и макЭто необязательно, поэтому группы 3 и 4 являются необязательными
  • \b Граница слова

Regex demo

...