Как сопоставить строку между двумя словами, но только «шкаф» из двух слов? - PullRequest
1 голос
/ 07 июня 2019

Я новичок в регулярных выражениях и пытаюсь запечатлеть определенный паттерн.Есть два слова (name1 и host), которые я хочу захватить между ними все, проблема в том, что иногда «все» между ними может содержать «name1».И если он содержит «name1», он включает в себя все, начиная от предыдущего name1, до следующего слова «host».Таким образом, у меня в основном две "строки" из двух разных имен "name1".

Вот мой пример:

name1{want-this-string}host,name1{want-this-string}host,name1{dont-want-this-string},name1{dont-want-this-either}name1{want-this-string}host

и это регулярное выражение, которое я использую сейчас..

(?<=\bname1\b).*?(?=\bhost\b)

Мой ожидаемый вывод состоит в том, что он соответствует 3 {want-this-string}, а не {dont-want-this}.так в основном:

{want-this-string}{want-this-string}{want-this-string}

Но сейчас это захват первых двух {want this string}, а затем весь этот раздел

{dont-want-this-string},name1{dont-want-this-either}name1{want-this-string}

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Если у вас есть GNU grep, вы можете использовать

grep -oP '\bname1\{\K[^{}]*(?=}host\b)' file

С pcregrep (вы можете установить его на MacOS, если вы используете эту ОС), вы можете использовать его как

pcregrep -oM '\bname1\{\K[^{}]*(?=}host\b)' file

См. Демоверсию regex

Детали

  • \bname1\{ - целое слово name1 и { после
  • \K - оператор сброса совпадений, отбрасывающий все совпадение
  • [^{}]* - 0 или более символов, отличных от { и }
  • (?=}host\b) - справа от текущего местоположения должно быть целое слово }host.

См. Демоверсию grep :

s="name1{want-this-string}host,name1{want-this-string}host,name1{dont-want-this-string},name1{dont-want-this-either}name1{want-this-string}host"
grep -oP '\bname1\{\K[^{}]*(?=}host\b)' <<< "$s"

Выход:

want-this-string
want-this-string
want-this-string
1 голос
/ 07 июня 2019

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

(^name1|}name1)({.+?})?|(host,name1)({.+?})(host,name1)

, которую эта часть может быть значительно упрощена:

(host,name1)({.+?})(host,name1)

, и мы добавляем его сюда только для того, чтобы показать реализацию правой границы, чтобы захватить только первый экземпляр значения (host,name1).

Демо

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

RegEx

Если это выражение не было желательным, и вы хотите изменить его, перейдите по этой ссылке на regex101.com .

...