2015-09-20 3 views
0

Это мои входыКак я могу сделать свой общий REGEX?

Cream & Sugar > Chocolates > Cakes & Cherries 
Cream & Sugar > Chocolates > Cakes & Cherries > Ice > Cold Coffee 

Это мое регулярное выражение

(([A-Z][a-z]+)\s&\s([A-Z][a-z]+)).* 

Я хочу, чтобы мой выход, чтобы захватить третью группу из правой

one=Cream & Sugar 
one=Cakes & Cherries 

Моя регулярное выражение работает для первого входа, но а не второй вход. Регулярное выражение должно соответствовать всем входным данным, и первая группа должна захватывать третью группу справа всегда без пробела в конце. Я использую инструмент Regex Coach.

+0

Пожалуйста, попробуйте быть более конкретными в Вашем вопросе, показывая нужный матч («' всего input'»), а не только захватывает, и, возможно, с некоторым упором на то, что вы хотите, чтобы третья группа ** справа **. – Mariano

ответ

1

RegexCouch не поддерживает именованные группы и просмотр назад, такой случай, вы можете использовать:

.*(?:^|\>\s)([^>]+)(?=(?:\s(?:^|\>)[^>]+){2}$).* 

, чтобы соответствовать всей линии с желаемым выходом захваченного в 1-е группы.


При использовании регулярных выражений аромата, поддерживающем lookarounds, вы можете использовать:

(?m)(?<=^|\>\s)(?<one>[^>]+)(?=(?:\s(?:^|\>)[^>]+){2}$) 

DEMO

  • (?m) - многострочный режим,
  • (?<=^|\>\s) - положительный просмотра назад для НАЧАЛА линии , или >
  • (?<one>[^>]+) - согласующие выбраны слова
  • (?=(?:\s(?:^|\>)[^>]+){2}$) - позитивный взгляд Ахед для двух других элементов между > и > или конец строки,

Без lookarounds:

(?m)(?:^|\>\s)(?<one>[^>]+)(?:(?:\s(?:^|\>)[^>]+){2}$) 

DEMO

желательно выход фиксируется в группе <one>

Оба регулярных выражений дают (прямой или путем захвата групп) выход:

Cream & Sugar 
Cakes & Cherries 
+0

Решение не работает с инструментом тренера regex :(любые идеи, чтобы сделать его тренером regex совместимым? Спасибо. – Meow

+0

@Meow try with '(? M) (?:^| \> \ S) ([^>] +) (? = (?: \ s (?:^| \>) [^>] +) {2} $) ', используйте флаги' g' –

+0

@ m.cekiera- Вышеупомянутое решение идеально подходит для желаемых групп Но это не соответствует всей входной строке. Любые предложения, чтобы соответствовать всей строке с вашим решением? Спасибо! – Meow

0

Если вам не нужно, чтобы соответствовать пустые входы вы можете использовать:

word = [A-Z][a-z]+ 
group = (word)((\s>\s)(word))* 
regex = (group)(\s&\s(group)).* 

т.е. первая группа является обязательным = (group), а затем (space)&(space)(group) ноль или более раз. И то же самое для > (word): это необязательно.

+0

Ваше регулярное выражение захватывает только крем для первого входа и вторых входов. Мне нужно захватить Cream & Sugar и Cakes & Cherries соответственно. Благодарю. – Meow

+0

Извините, я забыл часть>. Я только что отредактировал свой ответ, чтобы справиться с этим. –

0

Вы можете сделать ERE с СЕПГ:

$ s=$(printf 'Cream & Sugar > Chocolates > Cakes & Cherries\nCream & Sugar > Chocolates > Cakes & Cherries > Ice > Cold Coffee\n') 
$ echo "$s" | sed -E 's/(.*>)?([^>]+)(>[^>]+){2}$/\2/' 
Cream & Sugar 
Cakes & Cherries 

Или BRE, если вам нужно использовать старые инструменты:

$ echo "$s" | sed 's/\(.*> \)\{0,\}\([^>][^>]*\)\(>[^>][^>]*\)\{2\}$/\2/' 
Cream & Sugar 
Cakes & Cherries 

Обратите внимание, что я проверяю это в OSX; ваш sed может использовать другие варианты ERE.

Эти решения просто используют > как разделитель, а это значит, что вам лучше использовать что-то другое, кроме регулярного выражения, чтобы разобрать это.

$ echo "$s" | awk -F' *> *' '{print $(NF-2)}' 
Cream & Sugar 
Cakes & Cherries 
+0

@ ghoti- Я использую инструмент тренера regex, не могу сделать ERE с sed. Благодаря! – Meow

+0

Я понятия не имею, что такое «инструмент тренера регулярных выражений», но команда «s» выполняет поиск по регулярному выражению и выводит результаты на основе распознанных паттернов. Независимо от того, какой инструмент вы используете, может, несомненно, понимать ERE. – ghoti

Смежные вопросы