Как сопоставить шаблон, который содержит подстроку - PullRequest
0 голосов
/ 04 марта 2019

У меня есть этот текст:

Testing some text {{ first_name | mask }} and another {{ city }} and again {{ state | mask_trail }}

Я хотел бы сопоставить только {{}}, которые содержат трубу |

Но когда я делаю что-то вроде

text.scan(/({{.*?\|+.*?}})/)

{{city}} также соответствует

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Я предполагаю (частично из-за примера в вопросе), что совпадения должны исключать строки, начинающиеся с "{{" и заканчивающиеся "}}", содержащие "|", которые также содержат "{{".Например, ни

"{{ a | {{ b }}"

, ни

"{{ a | {{ b }} c }}"

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

Вы можете получить желаемые соответствия следующим образом.

str = "Testing some text {{ first_name | mask }} and another {{ city }} " +
      "and again {{ state | mask_trail }}"

R = /
    {{         # match '{{'
    ((?!{{).)  # match one character not preceded by '{{'. Save in capture group 1
    *          # perform capture to group 1 zero or more times 
    \|         # match '|'
    \g<1>      # execute subroutine defined by capture group 1
    *          # perform preceding match zero or more times
    }}         # match '}}'
    /x         # free-spacing regex definition mode

или,в кратком виде,

R = /{{((?!{{).)*\|\g<1>*}}/

str.gsub(R).to_a
  #=> ["{{ first_name | mask }}", "{{ state | mask_trail }}"]

Я не смог использовать String # scan , потому что я не хотел возвращать содержимоеиз группы захвата.Поэтому я использовал String # gsub без блока, чтобы вернуть перечислитель, который генерирует совпадения, а затем преобразовал его в массив совпадений. Здесь - это обсуждение подпрограмм регулярного выражения или подвыражений.

Я позаимствовал (?!{{). из ответа @ Pushpesh.

0 голосов
/ 04 марта 2019

Использование может использовать это регулярное выражение,

{{(?:(?!{{).)*\|(?:(?!{{).)*}}

Объяснение:

  • {{ - Соответствует литералу {{
  • (?:(?!{{).)* - Соответствует любому тексту, кроме буквального {{, также называемого Закаленный жадный жетон
  • \| - Соответствует трубе | символ
  • (?:(?!{{).)* -Поправитьсоответствует любому тексту, кроме буквального {{
  • }} - соответствует буквальному }}

Демо 1

Кроме того, если есть такие вложенные шаблоны, и вы хотите соответствовать большинству внутренних шаблонов, вы можете использовать это регулярное выражение,

{{(?:(?!{{|}}).)*\|(?:(?!{{|}}).)*}}

Демо 2

Проверьте этот код Ruby,

re = /{{(?:(?!{{|}}).)*\|(?:(?!{{|}}).)*}}/
str = 'Testing some text{{ {{ first_name | mask }} }} and another {{ city }} and again {{ state | mask_trail }}'

str.scan(re) do |match|
    puts match.to_s
end

Выходы,

{{ first_name | mask }}
{{ state | mask_trail }}

Демонстрация Ruby онлайн

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