Регулярное выражение, захватывающее несколько групп, начиная с шаблона

#regex #dart

#регулярное выражение #dart

Вопрос:

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

  1. Название группы начинается с ${{
  2. Необязательная строка может следовать
  3. Название группы заканчивается }}
  4. Необязательный контент может следовать за заголовком

Примером может быть
'${{an optional title}} some optional content'

Вот несколько примеров входных данных и ожидаемых результатов

Ввод 1: '${{}} some text '

Результат 1: ['${{}} some text ']

Ввод 2: '${{title1}} some text1 ${{title 2}} some text2'

Результат 2: ['${{title1}} some text1 ', '${{title 2}} some text2']

Ввод 3 (третья группа отсутствует, так как отсутствует вторая конечная фигурная скобка)

'${{title1}} some text1 ${{}} some text2 ${{title2} some text3'

Результат 3 ['${{title1}} some text1 ', '${{}} some text2 ${{title2} some text3']

Ввод 4 (группа с пустым содержимым, за которой сразу следует другая группа)

'${{title1}}${{}} some text2'

Результат 4 ['${{title1}}', '${{}} some text2']

Любые предложения будут оценены!

Комментарии:

1. То, что вы описали, звучит для меня как ${{.*}}.* правильно ли я понимаю, к чему вы клоните?

2. Не совсем. Введенное вами регулярное выражение приведет только к одному совпадению, начиная с первого совпадающего ${{, найденного во входной строке, заканчивающейся в конце строки (жадное совпадение). При незначительном изменении на $ {{.*?}} оно выдаст три совпадения, но каждая соответствующая группа будет содержать только заголовок. Попробуйте regexpal.com против ${{title1}}content1 ${{}}content2 $ {{title3}}content3 Спасибо за ваше предложение

3. Какой язык программирования (или разновидность регулярных выражений) вы используете?

4. Я мой код написан на Dart, но если вы сможете найти правильное регулярное выражение для js, я думаю, все будет хорошо

Ответ №1:

Вы можете добиться этого с помощью прогнозов. Попробуйте использовать следующий шаблон:

 ${{.*?}}.*?(?=${{.*?}}|$)
  

ДЕМОНСТРАЦИЯ.

Разбивка:

 ${{.*?}}    # Matches a "group" (i.e., "${{}}") containing zero or more chars (lazy).
.*?              # Matches zero or more characters after the "group" (lazy).
(?=              # Start of a positive Lookahead.
  ${{.*?}}  # Ensure that the match is either followed by a "group"...
|                # Or...
  $              # ..is at the end of the string.
)                # Close the Lookahead.
  

Комментарии:

1. Спасибо миллион! Я был очень близок, хотя, глядя на прогнозы: D

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

3. В регулярных выражениях Dart поддерживается предварительный просмотр (который совместим с регулярными выражениями JavaScript). { Однако вам также следует избегать, это случайность обратной совместимости, которая делает его не синтаксической ошибкой для использования { , } что не является правильным диапазоном.

4. @lrn Это что-то особенное в регулярном выражении JavaScript? AFAIK, фигурные скобки нужно экранировать, если вы не хотите соответствовать чему-то вроде {1} буквально.

5. Dart использует анализатор регулярных выражений V8, который более разрешителен, чем то, что требуется грамматике регулярных выражений ECMAScript. Например, оно допускает {a} в качестве регулярного выражения то, для чего в грамматике нет производства. Браузеры традиционно были более разрешительными, чем фактическая спецификация, и поскольку Dart для Интернета использует регулярные выражения браузера, мы решили разрешить то же самое изначально. Это все еще неверно . Правильное регулярное выражение ECMAScript должно экранировать все { символы за пределами диапазонов символов.