Есть ли конкретная причина плохой читаемости синтаксиса регулярных выражений?

160

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

Мы все согласны с тем, что selfDocumentingMethodName()гораздо лучше, чем e(). Почему это не относится и к регулярным выражениям?

Мне кажется, что вместо разработки синтаксиса однострочной логики без структурной организации:

var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})(0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

И это даже не строгий анализ URL!

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

string.regex
   .isRange('A-Z' || 'a-z')
   .followedBy('/r');

Какое преимущество дает чрезвычайно краткий синтаксис регулярного выражения, кроме как самого короткого из возможных операций и логического синтаксиса? В конечном счете, существует ли конкретная техническая причина плохой читаемости синтаксического дизайна регулярных выражений?

Viziionary
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
maple_shaft
1
Я попытался решить эту проблему с помощью библиотеки RegexToolbox. Пока что он портирован на C #, Java и JavaScript - см. Github.com/markwhitaker/RegexToolbox.CSharp .
Марк Уитакер
Было предпринято много попыток решить эту проблему, но культуру трудно изменить. см. мой ответ о словесных выражениях здесь . Люди тянутся к наименьшему доступному инструменту.
Паривар Сарафф

Ответы:

178

Существует одна большая причина, по которой регулярные выражения были спроектированы такими же краткими, как и они: они были разработаны для использования в качестве команд для редактора кода, а не в качестве языка для кодирования. Точнее, это edбыла одна из первых программ, использующих регулярные выражения и оттуда регулярные выражения начали свое завоевание мирового господства. Например, edкоманда g/<regular expression>/pвскоре создала отдельную программу под названием grep, которая используется до сих пор. Благодаря своей мощи они впоследствии были стандартизированы и использованы в различных инструментах, таких как sedиvim

Но хватит мелочи. Итак, почему это происхождение предпочитает краткую грамматику? Потому что вы не вводите команду редактора, чтобы прочитать ее еще раз. Достаточно того, что вы можете вспомнить, как собрать все вместе, и что вы можете делать с ним то, что хотите. Тем не менее, каждый символ, который вы вводите, замедляет процесс редактирования вашего файла. Синтаксис регулярных выражений был разработан для написания относительно сложных поисков одноразовым способом, и именно это доставляет людям головные боли, которые используют их в качестве кода для анализа некоторого ввода в программу.

cmaster
источник
5
регулярные выражения не предназначены для анализа. в противном случае - stackoverflow.com/questions/1732348/… . и головные боли.
njzk2
19
@ njzk2 Этот ответ на самом деле неправильный. HTML- документ - это не обычный язык, а открытый HTML- тег , который задает вопрос.
Random832,
11
Это хороший ответ, объясняющий, почему оригинальное регулярное выражение столь же загадочно, как и есть, но не объясняет, почему в настоящее время нет альтернативного стандарта с повышенной читабельностью.
Док Браун
13
Так что для тех, кто думает, что grepэто неправильно произносимое слово «схватить», оно на самом деле происходит от g/ re(для регулярного выражения) / p?
Хаген фон Айцен
6
@DannyPflughoeft Нет, это не так. Открытый тег - это просто <aaa bbb="ccc" ddd='eee'>, в нем нет вложенных тегов. Вы не можете вкладывать теги, что вы НЕСТ элементы (открытые теги, содержание , включая дочерние элементы, закрывающий тег), который этот вопрос не спрашивающих о разборе. HTML- теги являются обычным языком - балансировка / вложение происходит на уровне выше тегов.
Random832
62

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

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

Несмотря на это, регулярные выражения часто чрезмерно используются, то есть применяются даже тогда, когда другой инструмент будет намного лучше. Я не думаю, что синтаксис регулярных выражений ужасен . Но это явно намного лучше в коротких и простых шаблонах: архетипический пример идентификаторов в C-подобных языках [a-zA-Z_][a-zA-Z0-9_]*может быть прочитан с абсолютным минимумом знания регулярных выражений, и как только эта полоса будет достигнута, она будет и очевидной, и лаконичной. Требовать меньше персонажей - это не плохо, а совсем наоборот. Быть кратким - это добродетель, если вы остаетесь понятными.

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

Итак, почему они терпят неудачу в более сложных случаях? Я вижу три основные проблемы:

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

    # This is not equivalent to the regex in the question
    # It's just a mock-up of what a grammar could look like
    url      ::= protocol? '/'? '/'? '/'? (domain_part '.')+ tld
    protocol ::= letter+ ':'
    ...
    
  2. Как мы могли видеть выше, пробелы, не имеющие особого значения, полезны для того, чтобы сделать форматирование более простым для глаз. То же самое с комментариями. Регулярные выражения не могут этого сделать, потому что пробел - это просто литерал ' '. Обратите внимание: некоторые реализации допускают «подробный» режим, в котором пропуски игнорируются и возможны комментарии.

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

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

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

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

Тулаинс Кордова
источник
9
I don't know enough about the early years of computing to explain how regular expressions came to be so popular.Однако мы можем рискнуть предположить: базовый механизм регулярных выражений очень прост в реализации, гораздо проще, чем эффективный анализатор без контекста.
Бизиклоп
15
@biziclop Я бы не стал переоценивать эту переменную. Yacc, у которого, по-видимому, было достаточно предшественников, чтобы называться « еще одним компилятором компилятора», был создан в начале 70-х годов и был включен в Unix по grepсравнению с предыдущей версией (версия 3 против версии 4). Похоже, что первое широкое использование регулярных выражений было в 1968 году.
Я могу использовать только то, что нашел в Википедии (поэтому я не буду в это верить на 100%), но в соответствии с этим, yaccбыла создана в 1975 году целая идея парсеров LALR (которые были среди первого класса практически используемых парсеров их kind) возникла в 1973 году. В то время как первая реализация движка regexp, скомпилированная JIT-выражениями (!), была опубликована в 1968 году. Но вы правы, трудно сказать, что это заделало, на самом деле трудно сказать, когда регулярные выражения начали «принимать». выкл». Но я подозреваю, что как только они были введены в текстовые редакторы, которые они использовали, они захотели использовать их и в своем программном обеспечении.
Бизиклоп
1
@ jpmc26 открой свою книгу «Хорошие части JavaScript для главы Regex».
Viziionary
2
with very few differences between dialectsЯ бы не сказал, что это «очень мало». Любой предопределенный символьный класс имеет несколько определений между разными диалектами. И есть также причуды разбора, определенные для каждого диалекта.
2012 г.
39

Историческая перспектива

Статья в Википедии довольно подробно рассказывает о происхождении регулярных выражений (Kleene, 1956). Оригинальный синтаксис был относительно прост только *, +, ?, |и группировка (...). Это было кратко ( и читабельно, оба не обязательно противоположны), потому что формальные языки, как правило, выражаются в кратких математических обозначениях.

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

Помимо строковых регулярных выражений

Говоря об альтернативных синтаксисах, давайте посмотрим на тот, который уже существует ( cl-ppcre , в Common Lisp ). Ваше длинное регулярное выражение может быть проанализировано ppcre:parse-stringследующим образом:

(let ((*print-case* :downcase)
      (*print-right-margin* 50))
  (pprint
   (ppcre:parse-string "^(?:([A-Za-z]+):)?(\\/{0,3})(0-9.\\-A-Za-z]+)(?::(\\d+))?(?:\\/([^?#]*))?(?:\\?([^#]*))?(?:#(.*))?$")))

... и результаты в следующей форме:

(:sequence :start-anchor
 (:greedy-repetition 0 1
  (:group
   (:sequence
    (:register
     (:greedy-repetition 1 nil
      (:char-class (:range #\A #\Z)
       (:range #\a #\z))))
    #\:)))
 (:register (:greedy-repetition 0 3 #\/))
 (:register
  (:sequence "0-9" :everything "-A-Za-z"
   (:greedy-repetition 1 nil #\])))
 (:greedy-repetition 0 1
  (:group
   (:sequence #\:
    (:register
     (:greedy-repetition 1 nil :digit-class)))))
 (:greedy-repetition 0 1
  (:group
   (:sequence #\/
    (:register
     (:greedy-repetition 0 nil
      (:inverted-char-class #\? #\#))))))
 (:greedy-repetition 0 1
  (:group
   (:sequence #\?
    (:register
     (:greedy-repetition 0 nil
      (:inverted-char-class #\#))))))
 (:greedy-repetition 0 1
  (:group
   (:sequence #\#
    (:register
     (:greedy-repetition 0 nil :everything)))))
 :end-anchor)

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

Однако, если у вас начнутся проблемы с регулярными выражениями, их преобразование в этот формат может помочь вам расшифровать и отладить код. Это одно преимущество по сравнению со строковыми форматами, где может быть трудно обнаружить ошибку в один символ. Основным преимуществом этого синтаксиса является манипулирование регулярными выражениями с использованием структурированного формата вместо строкового кодирования. Это позволяет вам создавать и создавать такие выражения, как любая другая структура данных в вашей программе. Когда я использую приведенный выше синтаксис, это обычно происходит потому, что я хочу создавать выражения из более мелких частей (см. Также мой ответ на CodeGolf ). Для вашего примера мы можем написать 1 :

`(:sequence
   :start-anchor
   ,(protocol)
   ,(slashes)
   ,(domain)
   ,(top-level-domain) ... )

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

Также обратите внимание, что приведенная выше форма допускает (:regex "string")формы, так что вы можете смешивать краткие обозначения с деревьями. Все это приводит ИМХО к хорошей читаемости и комбинируемости; он решает три проблемы, выраженные delnan , косвенно (т.е. не на языке самих регулярных выражений).

Заключить

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

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

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


1. Вы можете предпочесть создавать свои выражения во время чтения, потому что регулярные выражения имеют тенденцию быть константами в приложении. Смотрите create-scannerи load-time-value:

'(:sequence :start-anchor #.(protocol) #.(slashes) ... )
CoreDump
источник
5
Возможно, я просто привык к традиционному синтаксису RegEx, но я не уверен, что 22 несколько читаемых строки легче понять, чем эквивалентное регулярное выражение в одну строку.
3
@ dan1111 «несколько читаемых» ;-) Хорошо, но если вам нужно иметь действительно длинное регулярное выражение, то имеет смысл определить подмножества, как digits, identи сочинять их. Как я понимаю, они обычно используют манипуляции со строками (конкатенацию или интерполяцию), что приводит к другим проблемам, таким как правильное экранирование. Поиск случаев \\\\`в пакетах emacs, например. Кстати, это еще хуже, потому что один и тот же управляющий символ используется как для специальных символов, таких как \nи, так \"и для синтаксиса регулярных выражений \(. Примером хорошего синтаксиса не является лиспис printf, где %dне конфликтует с \d.
coredump
1
Справедливо по поводу определенных подмножеств. Это имеет большой смысл. Я просто скептически отношусь к тому, что многословие - это улучшение. Это может быть проще для начинающих (хотя такие понятия greedy-repetitionне являются интуитивно понятными и все еще должны быть изучены). Тем не менее, он жертвует удобством использования для экспертов, так как гораздо сложнее увидеть и понять всю модель.
@ dan1111 Я согласен, что многословие само по себе не является улучшением. Что может быть улучшением, так это манипулирование регулярными выражениями с использованием структурированных данных вместо строк.
coredump
@ dan1111 Может быть, я должен предложить редактирование с использованием Haskell? Parsec делает это всего за девять строк; как однострочник do {optional (many1 (letter) >> char ':'); choice (map string ["///","//","/",""]); many1 (oneOf "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-."); optional (char ':' >> many1 digit); optional (char '/' >> many (noneOf "?#")); optional (char '?' >> many (noneOf "#")); optional (char '#' >> many (noneOf "\n")); eof}. С помощью нескольких строк, как обозначение длинной строки, domainChars = ...и section start p = optional (char start >> many p)это выглядит довольно просто.
CR Drost
25

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

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

Например, посмотрите на синтаксис URI в rfc3986 :

URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
hier-part     = "//" authority path-abempty
              / path-absolute
              / path-rootless
              / path-empty
...

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


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

CodesInChaos
источник
12

selfDocumentingMethodName () намного лучше, чем e ()

это? Есть причина, по которой большинство языков имеют {и} в качестве разделителей блоков, а не BEGIN и END.

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

Чтобы правильно ответить на ваш вопрос, вы должны понимать, что регулярное выражение исходит от тех времен, когда краткость была обязательной. Сегодня легко подумать, что XML-документ объемом 1 МБ не представляет особой проблемы, но мы говорим о тех днях, когда 1 МБ было достаточно вся ваша емкость. В то время также использовалось меньше языков, и регулярное выражение не было в миллионах миль от Perl или C, поэтому синтаксис был бы знаком программистам того времени, которые были бы рады изучению синтаксиса. Так что не было причин делать это более многословным.

gbjbaanb
источник
1
selfDocumentingMethodNameв целом согласились быть лучше , eпотому что программист интуиция не совпадает с реальностью в плане того , что на самом деле представляет собой читаемость или хороший код качества . Люди, которые соглашаются, ошибаются, но это так.
Леушенко
1
@Leushenko: Вы утверждаете, что e()это лучше, чем selfDocumentingMethodName()?
JacquesB
3
@JacquesB возможно не во всех контекстах (как глобальное имя). Но для ограниченных вещей? Почти наверняка. Определенно чаще, чем принято считать.
Леушенко
1
@Leushenko: Мне трудно представить себе контекст, в котором имя одной буквы лучше, чем более описательное имя. Но я думаю, это чистое мнение.
JacquesB
1
@MilesRout: пример на самом деле для e()самодокументированного имени метода . Можете ли вы объяснить, в каком контексте лучше использовать однобуквенные имена методов, а не описательные имена методов?
JacquesB
6

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

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

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

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

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

Падший ангел
источник
2

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

Например, строка регулярного выражения для URL может быть уменьшена примерно с:

UriRe = [scheme][hier-part][query][fragment]

чтобы:

UriRe = UriSchemeRe + UriHierRe + "(/?|/" + UriQueryRe + UriFragRe + ")"
UriSchemeRe = [scheme]
UriHierRe = [hier-part]
UriQueryRe = [query]
UriFragRe = [fragment]

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

toplel32
источник
2
К сожалению, большинство языков программирования не включают в себя функциональность, которая помогает при составлении регулярных выражений, и способ, которым работает захват групп, также не очень удобен для композиции.
CodesInChaos
1
Другие языки должны догонять Perl 5 в их поддержке "Perl-совместимых регулярных выражений". Субэкспрессии - это не то же самое, что просто конкатенация строк спецификации регулярных выражений. Захваты должны быть названы, не полагаясь на неявную нумерацию.
JDługosz
0

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

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

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

[ scsh великолепен по другим причинам, только одна из которых - его знаменитый текст подтверждений ]

Норман грей
источник
2
Perl6 делает! Посмотри на грамматику.
JDługosz
@ JDługosz Насколько я вижу, это больше похоже на механизм генераторов синтаксического анализатора, чем на альтернативный синтаксис для регулярных выражений. Но различие не может быть глубоким.
Норман Грей,
Это может быть замена, но не ограничивается той же силой. Вы можете перевести regedp во встроенную грамматику с 1: 1 соответствием модификаторов, но с более читаемым синтаксисом. Примеры, продвигающие это как таковые, находятся в оригинальном Апокалипсисе Perl.
JDługosz
0

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

Ваш пример regex.isRange(..).followedBy(..)связан как с синтаксисом конкретного языка программирования, так и, возможно, с объектно-ориентированным стилем (цепочка методов).

Как, например, будет выглядеть именно это регулярное выражение в C? Код должен быть изменен.

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

Авив Кон
источник
0

Совместимые с Perl механизмы регулярных выражений широко используются, предоставляя краткий синтаксис регулярных выражений, который понимают многие редакторы и языки. Как отметил @ JDługosz в комментариях, Perl 6 (не просто новая версия Perl 5, но совершенно другой язык) попытался сделать регулярные выражения более читабельными, создав их из отдельных элементов. Например, вот пример грамматики для анализа URL-адресов из Wikibooks :

grammar URL {
  rule TOP {
    <protocol>'://'<address>
  }
  token protocol {
    'http'|'https'|'ftp'|'file'
  }
  rule address {
    <subdomain>'.'<domain>'.'<tld>
  }
  ...
}

Разделение регулярного выражения, подобное этому, позволяет каждому биту быть индивидуально определенным (например, ограничивающим, domainчтобы быть буквенно-цифровым) или расширенным посредством подклассов (например, FileURL is URLэти ограничения protocolдолжны быть только "file").

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

Gaurav
источник