#.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
), но затем решил отказаться от этого, чтобы конкретно решить проблему ленивого / жадного сопоставления здесь.