Нужна помощь с регулярным выражением

#.net #regex

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

Вопрос:

В моем приложении .NET мне требуется проанализировать текст, который может содержать встроенные условия, например, это:

Вот некоторый текст. {{if: условие }} Вот некоторый условный текст. {{endif}} Вот еще текст.

И поэтому я написал следующее регулярное выражение, чтобы найти эти условия:

 {{if:(?<condition>[^}] )}}(?<value>. ){{endif}}
  

У меня это отлично работало и достигало того, чего я хочу, пока мне не пришлось иметь дело с вводом с двумя условиями:

{{if: условие }} содержимое {{endif}} какой-то другой контент {{if: condition2 }} content2 {{endif}}

В этом случае мое регулярное выражение собирает всю строку, начиная с {{if}} первого условия и заканчивая {{endif}} второго условия, из-за чего мое приложение работает некорректно.

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

РЕДАКТИРОВАТЬ: я должен был сказать, что содержимое в условиях также может содержать двойные фигурные скобки для представления других конструкций, и поэтому это не так просто, просто игнорировать их!

ПРИМЕЧАНИЕ: Существует также потенциальная проблема вложенных условий, но я не думаю, что мне придется беспокоиться об этом!

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

1. «Существует также потенциальная проблема вложенных условий, но я не думаю, что мне придется беспокоиться об этом!» — это хорошо, поскольку вы не можете анализировать вложенные структуры с помощью регулярных выражений (.NET) 🙂

2. @Porges, вы можете отлично проанализировать их, используя балансирующие группы .

3. @Lucero: Вау, спасибо! Некоторое время я искал что-нибудь, соответствующее рекурсивным выражениям Perls, и ничего не мог найти.

4. @Porges, я их опробовал, и они действительно работают очень хорошо. Но я по-прежнему предпочитаю использовать надлежащий анализатор для чего-либо более сложного (я написал движок для анализатора GOLD , который я использую для любых нужд синтаксического анализа DSL ).

5. Неплохо. Я никогда не слышал о балансирующих группах — они выглядят очень мощными. Нравится, когда я прихожу сюда, чтобы задать простой вопрос, и в итоге узнаю кучу новых вещей одновременно!

Ответ №1:

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

 {{if:(?<condition>[^}] )}}(?<value>. ?){{endif}}
  

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

1. Я бы внес две небольшие правки: разрешил использовать одиночные } буквы s в ‘condition’ и разрешил ‘value’ быть пустым: {{if:(?<condition>(?:(?!}}).)*)}}(?<value>.*?){{endif}} .

2. Я подумал о точно таких же предложениях (плюс одно относительно RegexOptions.SingleLine ), но затем решил отказаться от этого, чтобы конкретно решить проблему ленивого / жадного сопоставления здесь.