Регулярные выражения являются мощным инструментом в арсенале программиста, но - в некоторых случаях они не являются лучшим выбором или даже просто вредны.
Простой пример # 1 - анализ HTML с помощью регулярного выражения - известная дорога к многочисленным ошибкам. Возможно, это также относится к парсингу в целом.
Но есть ли другие области, в которых нет регулярных выражений?
PS: « Вопрос, который вы задаете, кажется субъективным и, вероятно, будет закрыт. » - поэтому я хочу подчеркнуть, что меня интересуют примеры, в которых использование регулярных выражений, как известно, вызывает проблемы.
Ответы:
Не используйте регулярные выражения:
Это не ограничивается HTML . Простой действительный XML не может быть разумно проанализирован с помощью регулярного выражения, даже если вы знаете схему и знаете, что она никогда не изменится.
Не пытайтесь, например, анализировать исходный код C # . Вместо этого проанализируйте его, чтобы получить значимую древовидную структуру или токены.
Что если вам нужно искать букву, как маленькую, так и заглавную? Если вы любите регулярные выражения, вы будете их использовать. Но не проще ли / быстрее / удобочитаемее использовать два поиска, один за другим? Скорее всего, в большинстве языков вы достигнете лучшей производительности и сделаете свой код более читабельным.
Например, пример кода в ответе Ingo является хорошим примером, когда вы не должны использовать регулярные выражения. Просто поищи
foo
, потом поbar
.Хорошим примером является фильтр непристойности. В общем, это не только плохая идея для реализации, но у вас может возникнуть соблазн сделать это с помощью регулярных выражений, и вы сделаете это неправильно. Есть много способов, которыми человек может написать слово, число, предложение и будет понят другим человеком, но не вашим регулярным выражением. Так что вместо того, чтобы поймать настоящую непристойность, ваше регулярное выражение будет тратить время на то, чтобы причинять боль другим пользователям.
Например, не проверяйте адрес электронной почты с помощью регулярного выражения. В большинстве случаев вы сделаете это неправильно. В редких случаях вы все сделаете правильно и закончите с ужасом кодирования длиной 6 343 символов .
Без правильных инструментов вы будете совершать ошибки. И вы заметите их в последний момент или, может быть, никогда. Если вас не волнует чистый код, вы напишите строку из двадцати строк без комментариев, пробелов и переносов строк.
Серьезно, если я возьму твой код и должен его просмотреть или изменить, я не хочу тратить неделю на то, чтобы понять последовательность символов длиной в двадцать строк.
источник
(?(DEFINE))
утверждениях;) Вы можете писать очень чистые регулярные выражения, используя их, и фактически, когда вы используете те, вы будете писать грамматики, которые очень похоже на то, что вы написали бы в yacc или в"<a href='foo'>stuff</a>"
. Современные регулярные выражения не имеют проблем с этим.Самое главное: когда вы анализируете язык, это не обычный язык .
HTML это не обычный язык и разбор его с регулярным выражением является не возможно (не только трудно или дорога к багги кода).
источник
В stackoverflow часто можно увидеть, как люди спрашивают регулярные выражения, чтобы выяснить, содержит ли данная строка то или иное. Это, ИМХО, изменение цели регулярного выражения. Даже если решение существует (с использованием негативных утверждений за кадром или тому подобного), часто гораздо лучше использовать регулярное выражение для того, для чего оно было сделано, и обрабатывать отрицательный случай с помощью программной логики.
Пример:
источник
Два случая:
Когда есть более простой способ
Большинство языков предоставляют простую функцию, такую как INSTR, чтобы определить, является ли одна строка подмножеством другой. Если это то, что вы хотите сделать, используйте более простую функцию. Не пишите свое собственное регулярное выражение.
Если есть библиотека, доступная для выполнения сложных манипуляций со строками, используйте ее вместо написания собственного регулярного выражения.
Когда регулярные выражения недостаточно сильны
источник
Регулярные выражения не могут идентифицировать рекурсивные структуры . Это фундаментальное ограничение.
Возьмите JSON - это довольно простой формат, но поскольку объект может содержать другие объекты в качестве значений элементов (произвольно глубоких), синтаксис является рекурсивным и не может быть проанализирован с помощью регулярного выражения. С другой стороны, CSV может быть проанализирован с помощью регулярных выражений, поскольку он не содержит никаких рекурсивных структур.
В коротких регулярных выражениях шаблон не позволяет ссылаться на себя. Вы не можете сказать: в этот момент в синтаксисе снова соответствует весь шаблон. Иными словами, регулярные выражения совпадают только линейно, они не содержат стек, который позволил бы ему отслеживать, насколько глубоко это вложенный шаблон.
Обратите внимание, что это не имеет ничего общего с тем, насколько сложным или запутанным является формат. S-выражения действительно очень просты, но не могут быть проанализированы с помощью регулярного выражения. CSS2, с другой стороны, является довольно сложным языком, но не содержит рекурсивных структур и поэтому может быть проанализирован с помощью регулярного выражения. (Хотя это не так для CSS3 из-за выражений CSS, которые имеют рекурсивный синтаксис.)
Так что это не потому, что это некрасиво, сложно или подвержено ошибкам при разборе HTML с использованием только регулярных выражений. Дело в том, что это просто невозможно .
Если вам нужно проанализировать формат, который содержит рекурсивные структуры, вам необходимо по крайней мере дополнить использование регулярных выражений стеком, чтобы отслеживать уровень рекурсивных структур. Это обычно, как работает парсер. Регулярные выражения используются для распознавания «линейных» частей, в то время как пользовательский код вне регулярного выражения используется для отслеживания вложенных структур.
Обычно такой анализ разбивается на отдельные фазы. Токенизация - это первая фаза, где регулярные выражения используются для разделения входных данных на последовательность «токенов», таких как слова, знаки препинания, скобки и т. Д. Синтаксический анализ - это следующая фаза, на которой эти токены разбираются в иерархическую структуру, синтаксическое дерево.
Поэтому, когда вы слышите, что HTML или C # не могут быть проанализированы с помощью регулярных выражений, имейте в виду, что регулярные выражения по-прежнему являются важной частью синтаксических анализаторов. Вы просто не можете разобрать такой язык, используя только регулярные выражения и никакой вспомогательный код.
источник