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

Существует популярная цитата от Jamie Zawinski :

  

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

Как следует понимать эту цитату?

200 голосов | спросил IQAndreas 9 Jpm1000000pmThu, 09 Jan 2014 21:54:10 +040014 2014, 21:54:10

17 ответов


220

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

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

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

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

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

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

ответил 9 Jpm1000000pmThu, 09 Jan 2014 22:28:00 +040014 2014, 22:28:00
95

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

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

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

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

ответил ChrisF 11 +04002010-10-11T17:32:33+04:00312010bEurope/MoscowMon, 11 Oct 2010 17:32:33 +0400 2010, 17:32:33
69

Это в основном шутка, хотя и с истиной.

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

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

  

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

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

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

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

ответил Karl Bielefeldt 9 Jpm1000000pmThu, 09 Jan 2014 22:52:44 +040014 2014, 22:52:44
53

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

  

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

     
    

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

  
     

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

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

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

ответил IQAndreas 9 Jpm1000000pmThu, 09 Jan 2014 22:37:43 +040014 2014, 22:37:43
30

В этой цитате есть несколько вещей.

  1. quote - это повторение ранней шутки:

      

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

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

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

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

ответил Jeffery Thomas 9 Jpm1000000pmThu, 09 Jan 2014 22:24:07 +040014 2014, 22:24:07
21

RegularExpressionsarenoworsetoreadormaintainthananyotherunformattedcontent;. Indeedaregexisprobablyeasiertoreadthanthispieceoftexthere-butunfortunatelytheyhaveabadreputationbecausesomeimplementationsdon'tallowformattingandpeopleingeneraldon'tknowthatyoucandoit

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


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

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


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

(? x) # включает комментарии, поэтому весь этот блок можно использовать в регулярном выражении.
^ # начало строки

(?: # начало группы не захвата
  [^,] * + # как можно больше не запятых, но не требуется
  , # a запятая
) # end не захватывающая группа
{21} # 21 предыдущего объекта (т. Е. Группы)

[^,] * + # как можно больше не запятых, но не требуется

$ # конец строки

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


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

ответил Peter Boughton 11 +04002010-10-11T17:49:39+04:00312010bEurope/MoscowMon, 11 Oct 2010 17:49:39 +0400 2010, 17:49:39
14

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

ответил Frank Shearar 29 +04002010-10-29T17:06:40+04:00312010bEurope/MoscowFri, 29 Oct 2010 17:06:40 +0400 2010, 17:06:40
14

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

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

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

ответил Guffa 11 +04002010-10-11T17:33:43+04:00312010bEurope/MoscowMon, 11 Oct 2010 17:33:43 +0400 2010, 17:33:43
10

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

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

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

ответил Ampt 9 Jpm1000000pmThu, 09 Jan 2014 22:10:36 +040014 2014, 22:10:36
7

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

  • Во-первых, вы не решили исходную проблему.
    Вероятно, это связано с тем, что регулярные выражения часто предлагают неполные решения для общих проблем.
  • Во-вторых, вы добавили дополнительные трудности, связанные с решением, которое вы выбрали.
    В случае регулярных выражений дополнительная трудность, вероятно, относится к сложности, ремонтопригодности или дополнительной сложности, связанной с тем, что регулярные выражения соответствуют задаче, которую она не должна была решать.
ответил tylerl 6 TueEurope/Moscow2011-12-06T03:25:32+04:00Europe/Moscow12bEurope/MoscowTue, 06 Dec 2011 03:25:32 +0400 2011, 03:25:32
7

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

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

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

Сначала у меня возникли проблемы, чтобы понять этот комикс, потому что это была ссылка на цитату Завинского, и цитату из песни Jay-z, и ссылку на Программа GNU --help -z флаг 2 , поэтому для меня было слишком много культуры, чтобы понять это.

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

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

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

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

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

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

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

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

sub'x {локальные $ _ = поп; суб '_ {$ _ > = $ _ [0
] $ _ [1]: $ "} _ (1, '*') ._ (5, '-') ._ (4
..? '*') $ /._ (6, '|') ($ _ > 9 'X': $ _ > 8
? '/':. $ ") ._ (8, '|') $ /._ (2, '*') ._ (
7, '-'.) ._ (3, '*') $ /} печать $ /х ($ =).
х (10) х (++ $ х /10) .x ($ х% 10), а & л; & GT ;;

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

# Эффективно сочетать строку с одной кавычкой ...
m {'# открытая одиночная кавычка
    [^ \\ '] * # любые неспецифические символы (т. е. не обратная косая черта или одинарная кавычка)
    (?: #, тогда все ... `
    \\. # любой явно обратный символ
    [^ \\ '] * #, за которым следуют нестандартные символы
    ) * # ... повторяется ноль или более раз
    '# закрывающая одинарная кавычка
}Икс

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

ответил smonff 17 Jam1000000amFri, 17 Jan 2014 07:48:50 +040014 2014, 07:48:50
6

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

ответил Juha Autero 19 Maypm11 2011, 23:38:21
5

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

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

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

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

ответил Vatine 30 +04002010-10-30T12:10:04+04:00312010bEurope/MoscowSat, 30 Oct 2010 12:10:04 +0400 2010, 12:10:04
3

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

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

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

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

ответил Brad Clawsie 30 +04002010-10-30T10:44:03+04:00312010bEurope/MoscowSat, 30 Oct 2010 10:44:03 +0400 2010, 10:44:03
3

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

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

  

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

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

ответил dan mackinlay 8 AMpMon, 08 Apr 2013 10:59:45 +040059Monday 2013, 10:59:45
0

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

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

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

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

ответил Kaz 8 AMpMon, 08 Apr 2013 11:53:28 +040053Monday 2013, 11:53:28
0

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

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

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

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

ответил Peter Green 6 Mayam18 2018, 03:50:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132