Что подразумевается под «Теперь у вас две проблемы»?

200

Есть популярная цитата Джейми Завински :

Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения». Теперь у них две проблемы.

Как эта цитата должна быть понята?

IQAndreas
источник
46
Вторая проблема заключается в том, что они используют регулярные выражения и до сих пор не решили первую проблему, следовательно, 2 проблемы.
День
24
@Euphoric - на самом деле, хороший код является коротким - но не будучи загадочно кратким.
Steve314
24
@ IQAndreas: я думаю, что это должно быть полумюмизм. Сделанный комментарий гласит: если вы не будете осторожны, использование регулярных выражений может сделать вещи хуже, а не лучше.
FrustratedWithFormsDesigner
145
Некоторые люди, пытаясь что-то объяснить, думают: «Я знаю, я буду использовать цитату Джейми Завински». Теперь им нужно объяснить две вещи.
детально

Ответы:

220

Некоторые технологии программирования, как правило, недостаточно понятны программистам ( регулярные выражения , числа с плавающей запятой , Perl , AWK , IoC ... и другие ).

Это могут быть удивительно мощные инструменты для решения правильного набора проблем. В частности, регулярные выражения очень полезны для сопоставления регулярных языков. И в этом суть проблемы: мало кто знает, как описать обычный язык (это часть теории информатики / лингвистики, которая использует забавные символы - вы можете прочитать об этом в иерархии Хомского ).

При работе с этими вещами, если вы используете их неправильно, маловероятно, что вы действительно решили свою первоначальную проблему. Использование регулярных выражений для соответствия HTML (далеко слишком распространенное явление) будет означать , что вы будете пропустить крайние случаи. И теперь у вас все еще есть исходная проблема, которую вы не решили, и еще одна тонкая ошибка, возникающая при использовании неправильного решения.

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

Ключом к поддержке программного обеспечения является написание поддерживаемого кода. Использование регулярных выражений может противоречить этой цели. При работе с регулярными выражениями вы написали мини-компьютер (в частности, недетерминированный конечный автомат ) на специальном доменном языке. Легко написать эквивалент «Привет, мир» на этом языке и получить элементарную уверенность в нем, но дальнейшее развитие событий должно быть ограничено пониманием обычного языка, чтобы избежать написания дополнительных ошибок, которые очень сложно идентифицировать и исправить (потому что они не являются частью программы, в которой находится регулярное выражение).

Итак, теперь у вас есть новая проблема; Вы выбрали инструмент регулярного выражения для его решения (когда это неуместно), и теперь у вас есть две ошибки, которые труднее найти, потому что они скрыты в другом уровне абстракции.

Сообщество
источник
8
Я не уверен, что perl входит в список технологий, которые не совсем понятны программистам;)
crad
21
@crad больше того, что было сказано и о Perl ... Многие люди слышали, что он популяризируется там. Мне все еще нравится плавающая точка в разговоре о ранде: «Теперь у вас проблемы с 2.00000152»
56
@crad Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать Perl». Теперь у них проблемы с $ (^ @ #% () ^%) (#).
Майкл Хэмптон
4
@Jens, если что, дополнительная мощь PCRE по сравнению с традиционным регулярным выражением делает его более заманчивым и более сложным в обслуживании. Конечные автоматы, которым соответствует PCRE, исследуются в Расширении конечных автоматов для эффективного соответствия Perl-совместимых регулярных выражений ... и это нетривиальная вещь. По крайней мере , с традиционным регулярным выражением, можно получить их голова вокруг него не слишком много хлопот , как только необходимые понятия понятны.
6
Ты делаешь доброе дело. регулярные выражения - фактически второй, нетривиальный язык. Даже если первоначальный программист владеет основным языком и разновидностью регулярного выражения, добавление «второго языка» означает меньшие шансы, что сопровождающие будут знать оба. Не говоря уже о том, что читаемость регулярных выражений часто ниже, чем у «основного» языка.
JS.
95

Регулярные выражения - особенно нетривиальные - потенциально сложно кодировать, понимать и поддерживать. Вам нужно только взглянуть на количество вопросов в тегах «Переполнение стека», в которых респондент [regex]предположил, что ответом на их проблему является регулярное выражение и впоследствии застрял. Во многих случаях проблема может (и, возможно, должна) быть решена другим способом.

Это означает, что если вы решили использовать регулярное выражение, у вас теперь есть две проблемы:

  1. Первоначальная проблема, которую вы хотели решить.
  2. Поддержка регулярных выражений.

По сути, я думаю, что он означает, что вы должны использовать регулярные выражения, только если нет другого способа решения вашей проблемы. Другое решение, вероятно, будет легче кодировать, поддерживать и поддерживать. Это может быть медленнее или менее эффективно, но если это не так важно, простота обслуживания и поддержки должна быть главной заботой.

ChrisF
источник
27
И что еще хуже: они достаточно мощные, чтобы обмануть людей, пытаясь использовать их для анализа того, что они не могут, например, HTML. Посмотрите многочисленные вопросы по SO на тему "Как мне разобрать HTML?"
Фрэнк Шиарар
6
Для определенных ситуаций регулярное выражение является удивительным. Во многих других случаях не так много. На другом конце это ужасная яма отчаяния. Проблема часто возникает, когда кто-то узнает о них впервые и начинает видеть приложения повсюду. Другая известная поговорка: «Когда у вас есть единственный инструмент - молоток, все выглядит как гвоздь».
Тодд Уильямсон
3
Означает ли это, что по количеству вопросов в теге SO [c #] это самый сложный для понимания язык программирования?
2
Я бы предпочел увидеть сложное регулярное выражение, чем длинную серию вызовов строковых методов. OTOH, я действительно ненавижу видеть регулярные выражения, неправильно используемые для анализа сложных языков.
Кевин Клайн
5
«По сути, я думаю, он имеет в виду, что вы должны использовать регулярные выражения, только если нет другого способа решения вашей проблемы. Любое другое решение будет легче кодировать, поддерживать и поддерживать». - серьезно не согласен. Регулярные выражения - превосходные инструменты, вы просто должны знать их пределы. Многие задачи можно более элегантно кодировать с помощью регулярных выражений. (но, просто для примера, вы не должны использовать их для разбора HTML)
Кароли Хорват
69

В основном это шутливая шутка, хотя и с долей правды.

Есть некоторые задачи, для которых регулярные выражения отлично подходят. Однажды я заменил 500 строк написанного вручную кода синтаксического анализатора рекурсивного спуска одним регулярным выражением, для полной отладки которого потребовалось около 10 минут. Люди говорят, что регулярные выражения сложно понять и отладить, но подходящие для применения не так сложны для отладки, как огромный анализатор, разработанный вручную. В моем примере потребовалось две недели, чтобы отладить все крайние случаи решения без регулярных выражений.

Однако, перефразируя дядю Бена:

С большой выразительностью приходит большая ответственность.

Другими словами, регулярные выражения добавляют выразительность вашему языку, но это возлагает большую ответственность на программиста, выбирающего наиболее читаемый способ выражения для данной задачи.

Некоторые вещи изначально выглядят как хорошая задача для регулярных выражений, но это не так. Например, что-нибудь с вложенными токенами, например HTML. Иногда люди используют регулярные выражения, когда более простой метод более понятен. Например, string.endsWith("ing")это легче понять, чем эквивалентное регулярное выражение. Иногда люди пытаются втиснуть большую проблему в одно регулярное выражение, где более уместно разбить ее на части. Иногда люди не могут создать подходящие абстракции, повторяя регулярные выражения снова и снова вместо создания хорошо названной функции для выполнения той же работы (возможно, реализованной внутри с помощью регулярного выражения).

По какой-то причине регулярные выражения имеют странную тенденцию создавать слепую зону для нормальных принципов разработки программного обеспечения, таких как единая ответственность и DRY. Вот почему даже люди, которые их любят, иногда находят их проблемными.

Карл Билефельдт
источник
10
Разве дядя Бен также не говорил «отличные результаты, каждый раз»? Может быть, поэтому люди так счастливы с помощью регулярных выражений ...
Анджей Дойл
4
Проблема с регулярным выражением в отношении HTML, которая сбивает с толку неопытных разработчиков, заключается в том, что HTML имеет неконтекстную грамматику, а не регулярную: регулярное выражение может использоваться для некоторого простого анализа HTML (или XML) (например, получение URL-адреса из именованного тега привязки), но не подходит ни для чего сложного. Для этого подходит DOM-разбор. Связанное чтение: Хомская иерархия .
53

Джефф Этвуд (Jeff Atwood) приводит другую интерпретацию в сообщении блога, в котором обсуждается эта цитата: « Регулярные выражения: теперь у вас две проблемы» (спасибо Euphoric за ссылку)

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

Природа Perl поощряет использование регулярных выражений почти исключая все другие методы; они, безусловно, самый «очевидный» (по крайней мере, для людей, которые не знают ничего лучшего) способ добраться из пункта А в пункт Б.

Первая цитата слишком бойкая, чтобы воспринимать ее всерьез. Но с этим я полностью согласен. Вот что Джейми пытался сделать: не то, чтобы регулярные выражения были злом, как таковое, а чрезмерное использование регулярных выражений - зло.

Даже если вы действительно в полной мере понять регулярные выражения, вы бежите в The Golden Hammer проблемы, пытаясь решить проблему с регулярными выражениями, когда это было бы проще и понятнее , чтобы сделать то же самое с регулярным кодом (смотри также CodingHorror: Regex использование против злоупотребления Регексом ).

Есть еще одно сообщение в блоге, которое рассматривает контекст цитаты и более подробно, чем Этвуд: блог Джеффри Фридла: источник знаменитой цитаты «Теперь у вас две проблемы»

IQAndreas
источник
3
На мой взгляд, это лучший ответ, потому что он добавляет контекст. Критика регулярных выражений в jwz была так же интересна Perl, как и все остальное.
Evicatos
3
@Evicatos Еще одно исследование было проведено в той же теме 1997 года в другом сообщении в блоге: regex.info/blog/2006-09-15/247
IQAndreas
30

С этой цитатой происходит несколько вещей.

  1. Цитата является повторением более раннего анекдота:

    Всякий раз, когда сталкиваются с проблемой, некоторые люди говорят: «Давайте использовать AWK». Теперь у них есть две проблемы. - Д. Тилбрук

    Это шутка и настоящее копание, но это также способ выделить регулярное выражение как плохое решение, связав его с другими плохими решениями. Это здорово, ха-ха, только серьезный момент.

  2. Для меня - заметьте, эта цитата преднамеренно открыта для толкования - смысл прямой. Простое объявление идеи использования регулярного выражения не решило проблему. Кроме того, вы увеличили когнитивную сложность кода, добавив дополнительный язык с правилами, которые стоят отдельно от того, какой язык вы используете.

  3. Несмотря на смешную шутку, вам нужно сравнить сложность решения без регулярных выражений со сложностью решения регулярных выражений + дополнительную сложность включения регулярных выражений. Возможно, стоит решить проблему с регулярным выражением, несмотря на дополнительные затраты на добавление регулярных выражений.

Джеффри Томас
источник
21

RegularExpressionsarenoworsetoreadormaintainthananyotherunformattedcontent; indeedaregexisprobablyeasiertoreadthanthispieceoftexthere-butunfortunatelytheyhaveabadreputationbecausesomeimplementationsdon'tallowformattingandpeopleingeneraldon'tknowthatyoucandoit.

(Регулярные выражения не хуже для чтения или поддержки, чем для любого другого неформатированного контента; действительно, регулярное выражение, вероятно, легче читать, чем этот фрагмент текста здесь - но, к сожалению, у них плохая репутация, потому что некоторые реализации не позволяют форматирование и люди в целом не знаю, что ты можешь сделать это.)


Вот тривиальный пример:

^(?:[^,]*+,){21}[^,]*+$


Что на самом деле не так сложно читать или поддерживать, но еще проще, когда это выглядит так:

(?x)    # enables comments, so this whole block can be used in a regex.
^       # start of string

(?:     # start non-capturing group
  [^,]*+  # as many non-commas as possible, but none required
  ,       # a comma
)       # end non-capturing group
{21}    # 21 of previous entity (i.e. the group)

[^,]*+  # as many non-commas as possible, but none required

$       # end of string

Это немного чрезмерный пример (комментирование $сродни комментированию i++), но ясно, что не должно быть проблем с чтением, пониманием и поддержанием этого.


Пока вы четко понимаете, когда подходят регулярные выражения и когда они являются плохой идеей, в них нет ничего плохого, и в большинстве случаев цитата JWZ действительно не применяется.

Питер Боутон
источник
1
Конечно, но я не ищу обсуждения достоинств регулярных выражений, и я не хотел бы, чтобы это обсуждение проходило таким образом. Я просто пытаюсь понять, к чему он клонит.
Пол Биггар
1
Тогда ссылка в комментарии livibetter говорит вам, что вам нужно знать. Этот ответ просто указывает на то, что регулярные выражения не должны быть неясными, и, следовательно, цитата - это чепуха.
Питер Боутон
8
Какой смысл использовать *+? Как это отличается (функционально) от просто *?
Тимви
1
Хотя то, что вы говорите, может быть правдой, оно не отвечает на этот конкретный вопрос. Ваш ответ сводится к "по моему мнению, эта цитата обычно не соответствует действительности". Вопрос не в том, правда это или нет, а в том, что означает цитата.
Брайан Оукли
2
Там буквально нет смысла делать *+в этом случае; все привязано и может быть сопоставлено за один проход автоматом, который может рассчитывать до 22. Правильный модификатор на этих наборах без запятой просто старый *. (Более того, здесь также не должно быть различий между жадными и не жадными алгоритмами сопоставления. Это чрезвычайно простой случай.)
Донал Феллоуз
14

В дополнение к ответу ChrisF о том, что регулярные выражения «сложно кодировать, понимать и поддерживать», есть еще одно: они достаточно мощные, чтобы обмануть людей, пытаясь использовать их для анализа того, что они не могут, например HTML. Посмотрите многочисленные вопросы по SO на тему "Как мне разобрать HTML?" Например, самый эпичный ответ во всех SO!

Фрэнк Шиарар
источник
14

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

В лучшем случае использование регулярного выражения решает проблему, поэтому у вас есть только проблема обслуживания сложного кода. Если вы не совсем правильно понимаете регулярное выражение, у вас есть как исходная проблема, так и проблема с нечитаемым кодом, который не работает.

Иногда регулярные выражения называют кодом только для записи. Столкнувшись с регулярным выражением, которое требует исправления, часто быстрее начать с нуля, чем пытаться понять выражение.

Guffa
источник
1
Реальная проблема заключается в том, что регулярные выражения не могут реализовать, например, синтаксический анализатор, поскольку они не могут сосчитать, насколько глубоко они вложены в данный момент.
4
@ Thorbjørn Равн Андерсен: Это скорее ограничение, чем проблема. Это проблема, только если вы пытаетесь использовать регулярные выражения для этого, и тогда это не проблема с регулярными выражениями, это проблема с вашим выбором метода.
Гуффа
1
Вы можете просто использовать RE для лексера (ну, для большинства языков), но формальная сборка потока токенов в дерево разбора (то есть, разбор ) формально за ними.
Донал Феллоуз
10

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

Вы утверждаете, что он может выполнять работу с сотнями строк кода, но вы также можете утверждать, что 100 строк ясного и краткого кода лучше, чем одна строка регулярного выражения.

Если вам нужно какое-то доказательство этого: вы можете проверить этот SO Classic или просто прочесать тег SO Regex.

Ampt
источник
8
Ни одно из утверждений в вашем первом предложении не соответствует действительности. Regex не особенно сложен, и, как никакой другой инструмент, вам нужно знать его в совершенстве, чтобы решать проблемы с ним. Это просто FUD. Ваш второй абзац просто смешной: конечно, вы можете сделать аргумент. Но это не очень хорошо.
Конрад Рудольф
1
@KonradRudolph Я думаю, тот факт, что существует множество инструментов генерации и проверки регулярных выражений, показывает, что регулярное выражение является сложным механизмом. Он не предназначен для чтения человеком (по замыслу) и может привести к полному изменению потока для кого-то, кто изменяет или пишет фрагмент кода, который использует регулярные выражения. Что касается второй части, я думаю, что это ясно из ее обширной группировки знаний о P.SE и высказывания «Отладка кода вдвое сложнее, чем его написание, поэтому, если вы пишете самый умный код, какой только можете», вы по определению недостаточно умны, чтобы его отладить "
Ampt
2
Это не правильный аргумент. Да, конечно, регулярные выражения сложны. Но так же, как и другие языки программирования. Regex значительно менее сложен, чем большинство других языков, и инструменты, которые существуют для regex, затмеваются инструментами разработки для других языков (FWIW, я интенсивно работаю с regex, и я никогда не использовал такие инструменты…). Простая истина в том, что даже сложные регулярные выражения проще, чем эквивалентный код синтаксического анализа без регулярных выражений.
Конрад Рудольф
@KonradRudolph Я думаю, что у нас есть принципиальное несогласие с определением слова «простой». Я скажу вам, что регулярное выражение может быть более эффективным или даже более мощным, но я не думаю, что это простое слово, которое приходит в голову кому-либо, когда вы думаете о регулярном выражении.
Ampt
Возможно, мы понимаем, но мое определение действенно: я имею в виду простое, то есть простое для понимания, простое в обслуживании, небольшое количество скрытых ошибок и т. Д. Конечно, сложное регулярное выражение на первый взгляд будет не очень понятным. Но то же самое относится и к эквивалентному коду без регулярных выражений. Я никогда не говорил, что регулярные выражения просты. Я говорю, что они проще - я сравниваю. Это важно
Конрад Рудольф
7

Значение имеет две части:

  • Во-первых, вы не решили исходную проблему.
    Это, вероятно, относится к тому факту, что регулярные выражения часто предлагают неполные решения общих проблем.
  • Во-вторых, вы добавили дополнительные трудности, связанные с выбранным решением.
    В случае регулярных выражений дополнительная трудность, вероятно, связана со сложностью, ремонтопригодностью или дополнительной трудностью, связанной с тем, чтобы регулярные выражения соответствовали проблеме, которую не предполагалось решать.
tylerl
источник
7

Как вы просите об этом в 2014 году, было бы интересно сосредоточиться на идеологиях языков программирования контекста 1997 года по сравнению с сегодняшним контекстом. Я не буду вступать в эту дискуссию здесь, но мнения о Perl и самом Perl сильно изменились.

Тем не менее, чтобы остаться в контексте 2013 года ( de l'eau a coulé sous les ponts depuis), я бы посоветовал сосредоточиться на реконструкции в цитатах, используя известный комикс XKCD, который является прямой цитатой из фильма Джейми Завински :

Комикс из XKCD о регулярных выражениях, Perl и проблемах

Во- первых у меня были проблемы , чтобы понять этот комикс , потому что это была ссылка на Завински цитатой, и цитата из Джей-Z тексты песен, и ссылка ГНУ program --help -zфлаг 2 , так, что это было слишком много культуры для меня , чтобы понять это.

Я знал, что это было весело, я чувствовал это, но я действительно не знал, почему. Люди часто шутят по поводу Perl и регулярных выражений, тем более, что это не самый хиппикий язык программирования, на самом деле не знаю, почему он должен быть веселым ... Может быть, потому что Perl-монгеры делают глупости .

Таким образом, первоначальная цитата кажется саркастической шуткой, основанной на реальных проблемах (боль?), Вызванных программированием с помощью инструментов, которые причиняют боль. Точно так же, как молоток может повредить масону, программируя с помощью инструментов, которые разработчик не выбрал бы, если бы мог причинить вред (мозг, чувства). Иногда возникают большие споры о том, какой инструмент является лучшим, но он почти бесполезен, потому что это проблема вашего вкуса или вкуса вашей команды программистов , культурных или экономических причин. Еще один отличный комикс XKCD об этом:

Комикс из XKCD о дебатах по инструментам программирования

Я могу понять людей, испытывающих боль от регулярных выражений, и они верят, что другой инструмент лучше подходит для того, для чего предназначены регулярные выражения. Когда @ karl-bielefeldt отвечает на ваш вопрос с большой выразительностью, приходит большая ответственность , и регулярные выражения особенно обеспокоены этим. Если разработчик не заботится о том, как он обращается с регулярными выражениями, это в конечном итоге станет проблемой для людей, которые будут поддерживать код позже.

Я закончу с этим ответом о воссоздании цитат цитатой, показывающей типичный пример из Perl Best Practices Дамиана Конви (книга 2005 года).

Он объясняет, что пишет шаблон так:

m{'[^\\']*(?:\\.[^\\']*)*'}

... не более приемлемо, чем писать такую ​​программу :

sub'x{local$_=pop;sub'_{$_>=$_[0
]?$_[1]:$"}_(1,'*')._(5,'-')._(4
,'*').$/._(6,'|').($_>9?'X':$_>8
?'/':$")._(8,'|').$/._(2,'*')._(
7,'-')._(3,'*').$/}print$/x($=).
x(10)x(++$x/10).x($x%10)while<>;

Но это может быть переписано , это все еще не симпатично, но по крайней мере это теперь выживаемо.

# Match a single-quoted string efficiently...
m{ '            # an opening single quote
    [^\\']*     # any non-special chars (i.e., not backslash or single quote)
    (?:         # then all of...`
    \\ .        # any explicitly backslashed char
    [^\\']*     #    followed by any non-special chars
    )*          # ...repeated zero or more times
    '           # a closing single quote
}x

Этот вид кода прямоугольной формы является второй проблемой, а не регулярными выражениями, которые могут быть отформатированы понятным, понятным и читаемым способом.

smonff
источник
2
/* Multiply the first 10 values in an array by 2. */ for (int i = 0 /* the loop counter */; i < 10 /* continue while it is less than 10 */; ++i /* and increment it by 1 in each iteration */) { array[i] *= 2; /* double the i-th element in the array */ }
5gon12eder
6

Если есть что-то, чему вы должны научиться у информатики, это иерархия Хомского . Я бы сказал, что все проблемы с регулярными выражениями возникают из-за попыток синтаксического анализа контекстной грамматики. Когда вы можете наложить ограничение (или думаете, что можете наложить ограничение) на уровни вложенности в CFG, вы получите эти длинные и сложные регулярные выражения.

Юха Аутеро
источник
1
Да! Люди, которые изучают регулярные выражения без этой части знания CS, не всегда понимают, что есть некоторые вещи, которые математически не может сделать регулярное выражение .
Бензадо
5

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

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

Поэтому, если кто-то привык «ага, мне нужно разбирать текст на части, я буду использовать регулярное выражение», то легко пойти по этому пути, когда вам нужно что-то, что ближе к автомату с нажатием, парсеру CFG или еще более мощные грамматики. Это обычно заканчивается слезами.

Итак, я думаю, что цитата - это не столько кричащие регулярные выражения, они имеют свое применение (и они хорошо используются, они действительно очень полезны), но чрезмерная зависимость от регулярных выражений (или, в частности, некритический их выбор) ,

Vatine
источник
3

JWZ просто сошел с ума от этой цитаты. регулярные выражения ничем не отличаются от любой языковой функции - их легко испортить, сложно использовать элегантно, иногда мощно, иногда неуместно, часто хорошо документировано, часто полезно.

То же самое можно сказать и для арифметики с плавающей запятой, замыканий, ориентации на объекты, асинхронного ввода-вывода или чего-либо еще, что вы можете назвать. Если вы не знаете, что делаете, языки программирования могут огорчить вас.

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

не откладывайте использование регулярных выражений (или любой другой языковой функции), потому что саморекламируемый блоггер делает неквалифицированные заявления. Попробуйте сами и посмотрите, что работает для вас.

Брэд Клоузи
источник
1
Кстати, арифметика с плавающей запятой намного сложнее, чем RE, но выглядит проще. Осторожно! (По крайней мере, хитрые RE имеют тенденцию выглядеть опасно.)
Donal Fellows
3

Мой любимый подробный ответ на этот вопрос дает знаменитый Роб Пайк в блоге, воспроизведенном из внутреннего комментария кода Google: http://commandcenter.blogspot.ch/2011/08/regular-expressions-in-lexing- and.html

В итоге, дело не в том, что они плохие , а в том, что они часто используются для задач, для которых они не обязательно подходят, особенно когда речь идет о лексизировании и анализе некоторого ввода.

Регулярные выражения сложно написать, сложно написать хорошо и они могут быть дорогостоящими по сравнению с другими технологиями ... С другой стороны, лексеры довольно легко написать правильно (если не так компактно), и их очень легко протестировать. Попробуйте найти буквенно-цифровые идентификаторы. Не так сложно написать регулярное выражение (что-то вроде «[a-ZA-Z _] [a-ZA-Z_0-9] *»), но на самом деле не так сложно написать простой цикл. Производительность цикла, тем не менее, будет намного выше и будет включать гораздо меньше кода под прикрытием. Библиотека регулярных выражений - большая вещь. Использование одного для разбора идентификаторов похоже на использование Ferrari для покупки молока.

Он говорит гораздо больше, утверждая, что регулярные выражения полезны, например, для одноразового сопоставления шаблонов в текстовых редакторах, но редко должны использоваться в скомпилированном коде и т. Д. Это стоит прочитать.

Дэн Маккинлей
источник
0

Это связано с эпиграммой Алана Перлиса № 34:

Строка является строгой структурой данных, и везде, где она передается, происходит многократное дублирование процесса. Это идеальное средство для сокрытия информации.

Поэтому, если вы выбираете символьную строку в качестве структуры данных (и, естественно, код на основе регулярных выражений в качестве алгоритмов для ее манипулирования), у вас возникает проблема, даже если она работает: плохой дизайн вокруг неправильного представления данных, которое трудно распространяться и неэффективно.

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

Kaz
источник
0

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

Однако по мере того, как регулярные выражения становятся более сложными, некоторые вопросы поднимают голову.

  1. Синтаксис регулярных выражений оптимизирован для простого сопоставления, большинство символов соответствуют друг другу. Это отлично подходит для простых шаблонов, но как только вы получите более двух уровней вложенности, вы получите нечто похожее на шум линий, чем на хорошо структурированный код. Я полагаю, что вы могли бы написать регулярное выражение в виде последовательности объединенных строк с отступами и комментариями между ними, чтобы показать структуру кода, но, похоже, это редко случается на самом деле.
  2. Только определенные типы соответствия текста хорошо подходят для регулярных выражений. Часто вы получаете быстрый и грязный синтаксический анализатор на основе регулярных выражений для какого-то языка разметки, работающего, но затем вы пытаетесь охватить больше угловых случаев и обнаруживаете, что регулярные выражения становятся все более сложными и все менее читаемыми
  3. Временная сложность регулярного выражения может быть не очевидной. Не так сложно получить шаблон, который отлично работает, когда он соответствует, но имеет сложность O (2 ^ n) при определенных случаях несоответствия .

Таким образом, слишком легко начать с задачи обработки текста, применить к ней регулярные выражения и в итоге получить две проблемы: исходную проблему, которую вы пытались решить, и работу с регулярными выражениями, которые пытаются решить (но не решают правильно) оригинальная проблема.

Питер Грин
источник