Возникает похожий вопрос, но он получил те же самые старые ответы, которые люди всегда дают о синтаксисе регулярных выражений, но дело не в этом, поэтому, пожалуйста, постарайтесь не дергать одни и те же старые ответы о синтаксисе регулярных выражений. Постарайтесь на этот раз быть немного более оригинальным и личным.
Синтаксис Regex очень компактный, почти слишком компактный, чтобы быть хорошим. Это похоже на код-гольф, и все согласны с тем, что код-гольф - плохая вещь в производственном коде. Однако большинство людей принимают синтаксис регулярных выражений, который кажется ... противоречивым, если не сказать больше.
Итак, некоторые распространенные способы защиты, которые, вероятно, можно услышать, включают:
Отвечать: Компактный
Прилавок: Разве мы все в наши дни не пришли к соглашению, что код должен быть грамотным, а переменная типа «client» лучше, чем «c»?
Отвечать: это "язык, специфичный для предметной области"
Прилавок: как насчет всех очень простых для понимания, некомпактных, не загадочных и, смею сказать, красивых доменных языков, таких как SQL или LINQ?
Отвечать: Это легко понять, если вы это знаете.
Прилавок: Большинство великих языков легко понять, даже если вы никогда их раньше не использовали. Например, любой может очень легко перейти на Python, даже если он никогда его раньше не видел. И почему люди защищают Regex, когда на него так сложно смотреть, а потом продолжают жаловаться на скобки Lisps?
Хорошо, теперь все стараются быть оригинальными и честными здесь, а не просто извлекать те же старые заученные ответы, которые программисты использовали 20 лет назад для разработки регулярных выражений. Если только вы действительно не верите, что это верные утверждения в наши дни.
Редактировать: Для справки, я знаю Regex много лет назад, часто использую их даже сегодня и могу даже попробовать их. Однако у меня внезапно возникло чувство, что, возможно, пришло время пересмотреть то, что я считал «истиной» о регулярных выражениях, и взглянуть на них с современной точки зрения. Главным образом потому, что вопросы принципов необходимы для дальнейшего развития, и поскольку так много новичков яростно жалуются на них, они не могут быть абсолютно правильными, поэтому я решил попробовать встать на место новичка и подумать о некоторых хороших моментах. против регулярного выражения.
Что касается субъективный, я не думаю, что это менее субъективно ИЛИ меньше связано с программистом, чем Шутки про программистов того времени. Напротив, это очень связано с программистом.
Что касается аргументированный, вот в чем суть вопроса. Чтобы получить веские аргументы в пользу устаревшего синтаксиса регулярных выражений, который может помочь новичкам лучше понять, почему регулярные выражения такие, какие они есть, и, что еще лучше, можно надеяться, что кто-то из новичков предложит лучшее решение. ослеплены «крутизной» регулярного выражения.
Цитировать:
The Perl 5.10 documentation for regexes has melted down into a heap of unreadable drivel because so many zany features have creeped into the syntax that no-one can write sensible documentation for it any more.
Вы пытаетесь сказать, что регулярное выражение стало недоступным? Что ж, тогда как хорошим программистам нам стоит подумать о их рефакторинге? Может быть, очистить и попробовать еще раз, как мы это сделали с некоторыми другими технологиями?
закройте пожалуйста этот вопрос, не связанный с программированием.
SQL - красивый предметный язык?
Замфира этого нет, не связанного с программированием. Это полностью о программировании и во многих смыслах. Нет необходимости объявлять неприемлемым то, что не решает сиюминутную проблему, потому что SO полна похожих вопросов, и сообщество в целом приняло такие вещи.
@Cheery, ну, я много работаю с SQL, и я нашел его симпатичным. Но вы, наверное, правы, это не очень красиво, когда я думаю об этом, просто чтобы вы видели, насколько мы больны, программисты :)
+1 для Edit, который устанавливает контекст вопроса, поощряет дух неуклонного улучшения и использует как «grok», так и «яростно» в одном абзаце.
Каков источник этой цитаты о 5.10?
это цитата из одного из ответов ниже, но сейчас не могу найти.





Еще одна проблема с регулярным выражением заключается в том, что существует множество его разновидностей. .Net regex vs php regex vs другое регулярное выражение, все выглядят одинаково, но не дают одинакового результата (иногда вообще нет результата).
Вот почему я склонен думать о регулярных выражениях как о «нерегулярных выражениях» ...
Посмотрите на другую сторону вопроса: как бы вы спроектировали новый синтаксис, который воплощал бы все функции, согласованность, лаконичность и надежность как регулярное выражение, но был бы более удобным для программистов?
Я недостаточно умен, чтобы придумать лучшее решение, но я очень надеюсь, что кто-то умный это сделал.
Брэд Гилберт, я собирался это сказать.
Я не считаю лаконичность добродетелью, когда она мешает пониманию. Вот попытка сделать BNF на C++: boost.org/doc/libs/1_35_0/libs/spirit/index.html
Если только я что-то не пропустил, грамматики Perl6 ничего не сделают для улучшения синтаксиса регулярных выражений. Однако они многое сделают для улучшения использовать для программистов.
работает !!
если есть простой для чтения язык, который имеет расширения на всех основных языках программирования и хорошо документирован и протестирован, а не так сжат, как регулярное выражение, но не слишком подробный (многословный = раздражающий), я хотел бы узнать об этом больше
Да, это очень хороший аргумент в пользу Regex! Я полностью с тобой согласен
Я бы защищал синтаксис регулярных выражений, потому что он (примерно) соответствует нотации, которую я выучил, когда проходил курс «Алгоритмы и машины». Это простой способ создать машину для приема указанного обычного языка.
Синтаксис регулярных выражений таков, потому что это действительно все, что вам нужно для полного описания поведения, которое вы ищете.
+1 Это хороший момент, о котором я забыл, и он дает действительный приоритет для странного синтаксиса, выходящего за пределы вычислительных возможностей десятилетий назад.
Как сказал Адам, есть ли что-нибудь лучше? Я содрогаюсь при мысли о попытке выполнить кучу операций strcmp вместо хорошего регулярного выражения. Как и любой выразительный язык, можно злоупотреблять регулярным выражением и создавать очень нечитаемые конструкции, но часто даже кажущееся нечитаемым регулярное выражение имеет гораздо больше смысла, чем эквивалентный процедурный код для достижения того же самого.
Без регулярного выражения вам пришлось бы написать свою собственную процедуру для синтаксического анализа, возврата, сравнения, хранения индексов, выполнения замен и управления всеми результатами. Regex дает вам все это в очень выразительной форме. Я не люблю повторять код, но если бы мне приходилось кодировать свой собственный синтаксический анализатор каждый раз, когда мне нужно было искать умеренно сложный шаблон ... я не знаю, что бы я делал.
Да, есть разные разновидности регулярных выражений, но самые популярные из них очень похожи, и на каком бы языке вы их ни использовали, обычно есть документация, которая поможет вам ее прочитать.
Вам следует рассматривать регулярные выражения как высокопроизводительные электроинструменты (я имею в виду электроинструменты в смысле строительной индустрии).
Если вы строите небольшой рабочий стол для своего сарая, вы не вытаскиваете пистолет для ногтей, бензопилу и промышленный маршрутизатор. Вы используете пилу, гвозди и молоток.
Точно так же нельзя построить 30-этажное здание без крана где-нибудь.
Идея состоит в том, чтобы использовать правильный инструмент для работы И, подходящий инструмент для вашего уровня квалификации.
Если вам нужно срубить дерево, убедитесь, что вы все знаете об отдаче, прежде чем запускать бензопилу. Если вы этого не сделаете, воспользуйтесь ручной пилой и сэкономьте время на поездке в больницу, чтобы заново прикрепить отрубленную конечность.
Я использую регулярные выражения так же, как и свою бензопилу - очень осторожно. Если вам неудобно пользоваться инструментом, не используйте его. Как только вы научитесь правильно его использовать, вам станет намного проще выполнять задачи быстрее.
+1 в каком-то смысле они являются электроинструментами. Но, может быть, нам стоит сделать более безопасные инструменты?
На самом деле это заговор, увековеченный Американской ассоциацией программистов-пенсионеров против сегодняшних молодых сучков, которые набили зубы на Python и Java. Нам нужно поддерживать чувство трепета и уважения к мистикам, чей ум преодолел проблемы крошечных основных воспоминаний и загадочных языков с помощью трехсимвольной мнемоники ... и понравилось это. В гору ... в обе стороны ... по снегу. :-)
Хорошо, это ОЧЕНЬ ХОРОШИЙ ответ, лол :)
Ваши контраргументы ложны. Вы знаете синтаксис регулярных выражений или ведете споры по незнанию? Это важный момент, чтобы выявить вашу предвзятость.
Это совсем не похоже на код-гольф. Я не уверен, что вы там связаны. Почему бы не пожаловаться на указатели или что-то еще, используя тот же аргумент?
Компактность регулярного выражения не имеет ничего общего с плохими именами переменных. Переменная с именем c может быть чем угодно. Синтаксис регулярного выражения не является ни двусмысленным, ни расплывчатым. Он точно описывает его узор.
Это DSL. Так что, если это так? Вы когда-нибудь пробовали делать сложные вещи на SQL? Это тоже большой беспорядок. То, что одно и то же требует большего набора текста и синтаксиса, не улучшает ситуацию. У большинства людей, которых я обучаю, есть проблемы с регулярными выражениями, потому что они не привыкли думать и разрабатывать шаблоны, а не потому, что синтаксис экзотичен.
Это легко понять, если вы это знаете. Что ж, это так. Электроинструменты не оптимизированы для новичков или людей, не желающих учиться. Я не жалуюсь на круглые скобки Lisp, но я не возражаю против синтаксиса регулярных выражений.
Если вы не хотите использовать регулярные выражения, не используйте их. Используйте функции обработки строк или синтаксические анализаторы. Воспользуйтесь другим инструментом. Пока вы этим занимаетесь, у меня впереди десять проблем, потому что я не плыву против течения и не виню инструменты в работе, которую я не могу выполнить.
Вам решать, сколько работы вы хотите выполнить. Найдите инструмент, который поможет вам быстрее всего, и изучите его. Если вам это не нравится, придумайте что-нибудь получше. А пока перестань жаловаться.
Извините за непонятность, да, я их знаю, использую и даже осмелюсь сказать, как они. Однако я пытаюсь найти веские аргументы против своих контраргументов, и ваши в некоторой степени верны.
Это маленький как в гольф. например "\ d" используется по сравнению с нотацией POSIX "[[: digit:]]". Тем не менее, я бы не хотел видеть подробную форму для "*?" квантификатор.
Я вообще не думаю, что это похоже на гольф. \d не предназначен для обфускации или использования функции умным, непреднамеренным или неожиданным образом. Классы символов POSIX не являются синонимами классов символов Perl, а в некоторых случаях они разные. Effectiveperlprogramming.com/blog/991
Второй пункт, касающийся переменной с именем c, довольно мощный.
Так оно и есть ... в основном по традиционным причинам, как вы правильно указали. Теперь
Лично я считаю, что регулярные выражения (по крайней мере, раздел, необходимый для рутинных задач) легко подобрать… день или два. Продвинутые вещи сложны (вторая половина книги MasteringRegExp), но и вам это не нужно так часто.
Очень хорошие аргументы! Спасибо, однако, если подумать об этом, это не спасло MFC или COBOL ... Но, тем не менее, мы позволили регулярному выражению быть королем ... странно, не правда ли?
Но вы должны помнить, что их преемники были «проще в использовании» и делали гораздо «больше с меньшими усилиями» .. Я думаю, что будет сложно превзойти регулярные выражения во втором отделе, даже если вы справитесь с первым.
Большая часть того, что я должен сказать, было адресовано Адамом и DGM, но я не думаю, что они хорошо охватывают ваш второй вопрос.
«как насчет всех очень простых для понимания, некомпактных, не загадочных и, смею сказать, красивых доменных языков, таких как SQL или LINQ?»
Я думаю, что хороший способ выразить ответ на этот вопрос - спросить, как бы вы использовали английский язык для объяснения регулярных выражений?
<TAG\b[^>]*>(.*?)</TAG>
Ищите «<TAG» - границу слова, равную нулю или более того, что не является «>», за которым следует «>», запоминайте ноль или более чего-либо, останавливаясь на первом «</TAG>»
Это довольно простое регулярное выражение. Действительно ли английскую форму легче понять? Не могли бы вы сделать лучше?
Регулярные выражения трудно читать, но так же трудно объяснить то, что вы от них хотите.
+1: Хорошие точки. «Если это было трудно писать, то это должно быть трудно понять. Почему ты думаешь, что они называют это код !?»
+1 отсюда тоже. Спасибо за хорошее замечание!
Так вот, если бы вы не объяснили, что это вообще не имело бы смысла!
@RCIX Это только если вы не знаете регулярное выражение.
Чтобы сыграть здесь адвоката дьявола; как бы вы заменили этот код элегантной альтернативой без регулярных выражений?
Точно. Кроме того, если вы действительно хотите, вы можете включить режим IgnorePatternWhitespace и красиво разбить ваше регулярное выражение по структуре на несколько строк и прокомментировать его, как я, если регулярное выражение очень сложное.
Отчасти проблема с регулярными выражениями заключается не в самом языке, а в том, для чего люди пытаются их использовать. Они будут писать строки и строки регулярных выражений, когда им действительно нужен довольно простой синтаксический анализатор.
Регулярные выражения отлично подходят для сопоставления простых и умеренно сложных подстрок и извлечения данных. Но на каком-то этапе сложности вам просто нужно вытащить компилятор-компилятор и написать настоящий парсер. Я думаю, что многие люди не понимают, что регулярные выражения предназначены в первую очередь для сопоставления, а не для синтаксического анализа.
Слышу, слышу! Регулярные выражения - один из моих любимых инструментов, но они не подходят даже для 10% того, что я делаю.
Я думаю, что язык регулярных выражений, подобный SQL, был бы интересным проектом. Я бы хотел, чтобы кто-нибудь это создал.
Почему у нет есть язык, на котором можно писать
LOOK FOR "<TAG"
THEN WORDBOUNDARY THEN ZERO-OR-MORE NOT('>') FOLLOWED-BY '>'
THEN ZERO-OR-MORE SOMETHING REMEMBERED
THEN NEAREST "</TAG>"
Я не уверен, кто является целевой аудиторией - не думаю, что буду использовать это, потому что я потратил все это время на изучение регулярных выражений.
Несомненно, набор «людей, которым необходимо использовать столь сложное выражение» в значительной степени соответствует набору программистов, которым ежедневно приходится иметь дело с такими же сложными и более сложными вещами?
+1 Согласился, я был бы очень рад иметь что-то подобное. В конце концов, даже новый синтаксис, если он хороший, может быстро уловиться. Отличным примером этого могут быть LINQ и Ruby. Оба прижились очень быстро (меньше, чем за год) благодаря своей красивой внешности.
Урргх - извините, но это выглядит ужасно. Я бы посоветовал использовать синтаксис пробелов / комментариев, чтобы вы могли разделить его логически и комментировать все, что может быть запутано любым, кто поддерживает код (включая вас через год;)
Ох, это было бы хорошо. форма SQL (язык строковых запросов)? : D
Конечно, я имею в виду, сколько времени может потребоваться, чтобы создать макрос на основе регулярного выражения для кодирования, генерирующего регулярный код регулярного выражения из недавно определенного SQL-подобного синтаксиса регулярного выражения, верно. ;)
Немного похоже на КОБОЛ
Фактически вы могли бы создать инструмент, который одним щелчком мыши переключался между таким синтаксисом и регулярным выражением. Считайте, что это своего рода «интерактивная справка», встроенная в IDE (или одноразовый веб-инструмент для ответа на вопросы, «что именно делает это сложное регулярное выражение», которые возникают время от времени). По теме: я мечтаю, что в одно из этих десятилетий у нас будет аналог Google Translate для компьютерных программ (то есть ввести блок кода / алгоритм в javascript, вывести эквивалентный код на Fortran или C# или описательный французский, и наоборот).
Они похожи на нотацию BNF и тому подобное, являясь основой многих хороших языковых спецификаций. Поэтому имеет смысл использовать такую нотацию в лексерах для обозначения классов ожидаемых символов. Базовые символы на самом деле не такие уж загадочные.
Затем я думаю, что пришла идея UNIX-do-all-you-can-in-a-one-line. После улучшений в сценариях sed и grep регулярные выражения приобрели новые возможности, но для них были сокращены обозначения. Ларри Уолл включил их в Perl как общий инструмент для анализа текста. Я предполагаю, что он сохранил компактность для одинарных строк, которые все еще были важны для Perl. И были сокращенные имена для общих классов символов, и еще больше возможностей было запрошено и дано регулярным выражениям. Конечно, поскольку Perl также был языком модулей, синтаксис регулярных выражений также работал в блоках операторов и использовал синтаксис, который был более широко известен.
Их включение в Java действительно заставило людей взглянуть на них, ИМО. Java не сделала ничего, чтобы их приспособить. В результате выражения с обратной косой чертой средней сложности превратились в густые джунгли обратной косой черты. Java предоставила регулярным выражениям новый рынок, если хотите, но это их самая ужасная форма. Если вы видели их и больше не обращали внимания, вы можете подумать, что регулярное выражение - это то, чего не должно быть.
Интересно, что при достаточно ясном синтаксисе для многословной версии Эмброуза кто-нибудь мог бы предложить модуль для Perl, который мог бы взять подробное регулярное выражение и «скомпилировать» его в компактное регулярное выражение, которое понимает Perl, используя более простые регулярные выражения через overload::constants или, возможно, Грамматика Parse::RecDescent.
Спасибо за довольно развернутый ответ. Честно говоря, я много лет пропускал Java, и интересно, что Java, возможно, принесла регулярные выражения в массы :)
Что ж, я не уверен в этом, просто если я видел умеренно сложный RE, который занимает пару минут для синтаксического анализа, обычно это был результат взрыва обратной косой черты, необходимого для Java. Остальные ссылки кажутся правдоподобными, если не актуальными.
Просматривая аналогичный вопрос, который вы упомянули, и ответы на него, я увидел несколько попыток создания «более дружелюбных» альтернативных синтаксисов как со стороны сторонников, так и противников регулярных выражений, какими мы их знаем сегодня.
Я обнаружил, что они менее читабельны, чем эквивалентные регулярные выражения.
Теперь, конечно, я регулярно использую регулярные выражения, поэтому я уверен, что мое удобство с ними является важной частью этого. Но моя основная проблема с ними заключалась не в незнании, а в том, что они быстро стали слишком большими, чтобы их можно было охватить сразу. Когда ваше 20-символьное регулярное выражение становится псевдоанглийским выражением размером 10 строк на 30 столбцов, становится намного труднее увидеть, как его части соотносятся друг с другом.
Возможно, кто-то предложит альтернативный синтаксис регулярным выражениям, который повсеместно будет более читаемым, даже в сложных случаях, но я утверждаю, что такой синтаксис по своей сути потребует некоторого эквивалента вызовов подпрограмм. Мы не пишем 200-строчные блоки кода приложения с 15 уровнями вложенной логики, потому что было бы монументальной задачей просто отслеживать ее логику, не говоря уже о том, чтобы выяснить, что она на самом деле делает. Если мы собираемся преобразовать регулярные выражения в более англоязычную форму, тогда возникнет та же проблема, и нам потребуются те же инструменты для управления ею.
необходимость подпрограмм - очень хороший момент и возможный камень преткновения для преемника. Но, с другой стороны, длинные регулярные выражения сами по себе плохие манеры, возможно
Регулярные выражения, как правило, имеют подпрограммы, но подпрограммы и аргументы названы так, что J. Random Newbie будет думать, что они выглядят как тарабарщина. Первоначально они напомнили мне, что произойдет, если кто-то сбросит случайные данные на один из старых принтеров кампуса, из-за чего он выбросит что угодно, от нескольких символов до нескольких десятков листов случайных символов. Работа с регулярным выражением похожа на работу с некоторыми из эзотерических языков вызова; все чрезвычайно лаконично и совершенно логично, читать их изначально ужасно, но написание их дает огромное представление о ценности взлома.
Регулярное выражение (по крайней мере, изначально) описывает регулярный язык. Регулярные языки обладают очень хорошими теоретическими свойствами в том смысле, что оба они могут быть описаны и описывать детерминированные конечные автоматы. DFA для нетривиальных регулярных выражений сложно кодировать вручную.
Что еще более важно, компиляторы регулярных выражений, используемые в серверной части Perl и т. д., Очень хороши в том, что они делают. Было бы очень сложно вручную настроить конкурентоспособный код.
Наконец, их существование во многом является историческим артефактом. Они существуют уже давно, пользуются популярностью, многие их знают. Инструмент, который у вас есть, и который могут поддержать другие люди, намного лучше, чем теоретический инструмент, которого еще не существует.
Если вас отталкивает только синтаксис, возможно, вам стоит подумать о комбинаторах синтаксического анализатора в Haskell. Они могут выражать надмножество одних и тех же идей и иметь более явный синтаксис.
Но все языки начинались с того, что не существовали, а с целью улучшения и удовлетворения потребностей. Как уже упоминалось, кто придумал LINQ?
Ну, шутливо, Эрик Мейер. ;) LINQ является потомком понятий монад, расширенных для обработки сортировки и упорядочения, и они восходят к Вадлеру и происходят из представлений списков, которые вы можете вернуться в SETL из 60-х годов. Мы склонны опираться на то, что было раньше, а не создавать целую ткань.
Pyparsing (http://pyparsing.wikispaces.com/Examples) - это библиотека Python, которая позволяет легко писать выражения, подобные регулярным выражениям, которые легко читаются, например, эти строки, которые будут анализировать «Hello, World!»:
from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!"
greet.parseString("Hello, World!")
Похоже, что библиотека очень близка к тому, чтобы соответствовать мощности регулярных выражений (см. Страницу примеров, упомянутую выше).
Pyparsing больше не размещается на wikispaces.com. Перейти к github.com/pyparsing/pyparsing
Другие намекали на это, но стоит прямо заявить:
Обычные языки не похожи на языки программирования. Они ближе к математической нотации.
Компактность и причудливость больше являются результатом попытки вывести точную нотацию из символов ASCII, чем преднамеренной попыткой краткости или запутывания.
Готов поспорить, все участники этого обсуждения согласятся, что для некоторых кодов регулярных выражений маленький нужно будет написать длинный абзац на английском языке, описывающий, что он делает. Любой язык, который можно использовать для того, что описывает даже простейшее регулярное выражение, вероятно, будет делать это с N строками кода, где N (вероятно) растет экспоненциально по сравнению с длиной самого регулярного выражения.
Из модуля Perl Regexp :: английский:
Regexp::English provides an alternate regular expression syntax, one that is slightly more verbose than the standard mechanisms. In addition, it adds a few convenient features, like incremental expression building and bound captures.
use Regexp::English;
my $re = Regexp::English
-> start_of_line
-> literal('Flippers')
-> literal(':')
-> optional
-> whitespace_char
-> end
-> remember
-> multiple
-> digit;
while (<INPUT>) {
if (my $match = $re->match($_)) {
print "$match\n";
}
}
Также было бы неплохо указать, если вы используете регулярное выражение знать. Под знать я имею в виду что-то на уровне способности отличить NFA от DFA.