Почему регулярные выражения так противоречивы? [закрыто]


212

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

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

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


9
если это дискуссия, то не должна ли она быть закрыта? но я вижу реальный вопрос там, так что, возможно, тег обсуждения не принадлежит?
RCIX

6
Без шуток. Вы поднимаете это, и люди начинают сходить с ума здесь.
Райан Флоренс

1
Приятное наблюдение и формулировка в вопросе!
imz - Иван Захарящев


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

Ответы:


136

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


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

1
Если вы знаете, как работает регулярное выражение, это совсем не проблема.
Шиплу Мокаддим

8
@ spacerier, это не медленные паттерны , это медленные движки . Большинство (современных) движков регулярных выражений не подходят для сложных паттернов (например, многие |или .*), потому что они используют стековую машину и возврат. Вот почему вы должны тщательно настроить регулярные выражения в Perl, Java, Python, Ruby… Механизмы регулярных выражений старого стиля ( grepнапример, в) сначала скомпилируют шаблон в DFA. После этого сложность шаблона в значительной степени не имеет значения. Я просто использовал Java и grep для одного и того же текста и шаблона: 22 минуты против 2 секунд. Вот наука: swtch.com/~rsc/regexp/regexp1.html
hagello

122

Создание регулярных выражений

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

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

Вот пример относительно пронумерованной группы захвата:

$ dupword = qr {\ b (?: (\ w +) (?: \ s + \ g {-1}) +) \ b} xi;
$ quoted = qr {(["']) $ dupword \ 1} x;

И вот пример превосходного подхода именованных захватов:

$dupword = qr{ \b (?: (?<word> \w+ ) (?: \s+ \k<word> )+ ) \b }xi;
$quoted  = qr{ (?<quote> ["'] ) $dupword  \g{quote} }x;

Грамматические регулярные выражения

Лучше всего , что эти именованные захваты могут быть помещены в (?(DEFINE)...)блок, так что вы можете отделить объявление от выполнения отдельных именованных элементов ваших шаблонов. Это заставляет их действовать скорее как подпрограммы в шаблоне.
Хороший пример такого рода «грамматического регулярного выражения» можно найти в этом и этом ответе . Это больше похоже на грамматическую декларацию.

Как последнее напоминает вам:

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

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

Вот еще один пример современного грамматического шаблона, этот для анализа RFC 5322: используйте 5.10.0;

$rfc5322 = qr{

   (?(DEFINE)

     (?<address>         (?&mailbox) | (?&group))
     (?<mailbox>         (?&name_addr) | (?&addr_spec))
     (?<name_addr>       (?&display_name)? (?&angle_addr))
     (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
     (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ; (?&CFWS)?)
     (?<display_name>    (?&phrase))
     (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

     (?<addr_spec>       (?&local_part) \@ (?&domain))
     (?<local_part>      (?&dot_atom) | (?&quoted_string))
     (?<domain>          (?&dot_atom) | (?&domain_literal))
     (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                   \] (?&CFWS)?)
     (?<dcontent>        (?&dtext) | (?&quoted_pair))
     (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

     (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&'*+-/=?^_`{|}~])
     (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
     (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
     (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

     (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
     (?<quoted_pair>     \\ (?&text))

     (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
     (?<qcontent>        (?&qtext) | (?&quoted_pair))
     (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                          (?&FWS)? (?&DQUOTE) (?&CFWS)?)

     (?<word>            (?&atom) | (?&quoted_string))
     (?<phrase>          (?&word)+)

     # Folding white space
     (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
     (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
     (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
     (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
     (?<CFWS>            (?: (?&FWS)? (?&comment))*
                         (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

     # No whitespace control
     (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

     (?<ALPHA>           [A-Za-z])
     (?<DIGIT>           [0-9])
     (?<CRLF>            \x0d \x0a)
     (?<DQUOTE>          ")
     (?<WSP>             [\x20\x09])
   )

   (?&address)

}x;

Разве это не замечательно - и великолепно? Вы можете взять грамматику в стиле BNF и перевести ее непосредственно в код, не теряя своей фундаментальной структуры!

Если вам по- прежнему недостаточно современных грамматических шаблонов , то великолепный Regexp::Grammarsмодуль Дамиана Конвея предлагает еще более чистый синтаксис и превосходную отладку. Вот тот же код для разбора RFC 5322, преобразованного в шаблон из этого модуля:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use Data::Dumper "Dumper";

my $rfc5322 = do {
    use Regexp::Grammars;    # ...the magic is lexically scoped
    qr{

    # Keep the big stick handy, just in case...
    # <debug:on>

    # Match this...
    <address>

    # As defined by these...
    <token: address>         <mailbox> | <group>
    <token: mailbox>         <name_addr> | <addr_spec>
    <token: name_addr>       <display_name>? <angle_addr>
    <token: angle_addr>      <CFWS>? \< <addr_spec> \> <CFWS>?
    <token: group>           <display_name> : (?:<mailbox_list> | <CFWS>)? ; <CFWS>?
    <token: display_name>    <phrase>
    <token: mailbox_list>    <[mailbox]> ** (,)

    <token: addr_spec>       <local_part> \@ <domain>
    <token: local_part>      <dot_atom> | <quoted_string>
    <token: domain>          <dot_atom> | <domain_literal>
    <token: domain_literal>  <CFWS>? \[ (?: <FWS>? <[dcontent]>)* <FWS>?

    <token: dcontent>        <dtext> | <quoted_pair>
    <token: dtext>           <.NO_WS_CTL> | [\x21-\x5a\x5e-\x7e]

    <token: atext>           <.ALPHA> | <.DIGIT> | [!#\$%&'*+-/=?^_`{|}~]
    <token: atom>            <.CFWS>? <.atext>+ <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom>        <.CFWS>? <.dot_atom_text> <.CFWS>?
    <token: dot_atom_text>   <.atext>+ (?: \. <.atext>+)*

    <token: text>            [\x01-\x09\x0b\x0c\x0e-\x7f]
    <token: quoted_pair>     \\ <.text>

    <token: qtext>           <.NO_WS_CTL> | [\x21\x23-\x5b\x5d-\x7e]
    <token: qcontent>        <.qtext> | <.quoted_pair>
    <token: quoted_string>   <.CFWS>? <.DQUOTE> (?:<.FWS>? <.qcontent>)*
                             <.FWS>? <.DQUOTE> <.CFWS>?

    <token: word>            <.atom> | <.quoted_string>
    <token: phrase>          <.word>+

    # Folding white space
    <token: FWS>             (?: <.WSP>* <.CRLF>)? <.WSP>+
    <token: ctext>           <.NO_WS_CTL> | [\x21-\x27\x2a-\x5b\x5d-\x7e]
    <token: ccontent>        <.ctext> | <.quoted_pair> | <.comment>
    <token: comment>         \( (?: <.FWS>? <.ccontent>)* <.FWS>? \)
    <token: CFWS>            (?: <.FWS>? <.comment>)*
                             (?: (?:<.FWS>? <.comment>) | <.FWS>)

    # No whitespace control
    <token: NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f]

    <token: ALPHA>           [A-Za-z]
    <token: DIGIT>           [0-9]
    <token: CRLF>            \x0d \x0a
    <token: DQUOTE>          "
    <token: WSP>             [\x20\x09]

    }x;

};


while (my $input = <>) {
    if ($input =~ $rfc5322) {
        say Dumper \%/;       # ...the parse tree of any successful match
                              # appears in this punctuation variable
    }
}

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

Современные шаблоны почти не имеют ничего общего с примитивными вещами, которым вас учили в вашем классе конечных автоматов.


9
ДА! ДА! Наконец, кто-то показывает отличный пример того, насколько читаемыми регулярные выражения могут быть с модификатором x. Я не могу поверить, как мало людей знают, что оно существует, не говоря уже о том, чтобы использовать его.
Шаббироб

1
@Shabbyrobe: это не просто /x. Это использует регулярные выражения грамматически, с (?&name)внутренними подпрограммами регулярных выражений, что действительно делает этот блеск.
2010 года

+1 Вы всегда узнаете что-то новое. Я не знал, что у PCRE было «ложное» условие для определений.
NikiC

5
Python также имеет re.VERBOSEфлаг.
Механическая улитка

3
Просто продолжайте, Ганна, и скажите, что я все еще поражен тем, на что люди пойдут, чтобы сделать регулярное выражение пригодным для использования.
Слэйтер Викторофф

68

Регулярные выражения - отличный инструмент, но люди думают: «Эй, какой замечательный инструмент, я буду использовать его, чтобы делать X!» где X - это то, для чего лучше использовать другой инструмент (обычно это парсер). Это стандартное использование молотка, когда вам нужна проблема с отверткой.


4
Просто помните, что большинство синтаксических анализаторов - анализаторы - все еще используют регулярные выражения для разбора своих вещей :-)
Jasper Bekkers,

62
Сказать, что парсеры используют регулярные выражения, все равно что сказать, что парсеры используют операторы присваивания. Это ничего не значит, пока вы не посмотрите, как они используются.
час. Оуэнс

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

1
Согласен, потому что RegEx должен быть мастером на все руки, поэтому его обработка требует огромных затрат. То, что использование механизма RegEx кажется простым, не означает, что это лучшее решение по сравнению с итеративным анализатором (порог, зависящий от разработчика). Один из моих любимых примеров split($pattern,$string)против PHP explode($delimiter,$string)- к счастью, первый обесценивается, но во многих кодах первый используется только тогда, когда ему нужна только мощь последних. Согласитесь, RegEx предоставляют простой инструмент для выполнения некоторых задач, но если вам не нужна вся мощь регулярных выражений, они
Rudu

4
Лексические анализаторы действительно могут использовать регулярные выражения. Они также известны как токенизаторы, но они не являются синтаксическими анализаторами (или анализаторами). Чтобы прочитать достаточно сложную строку, токенайзер должен использоваться для чтения строки как токенов (возможно, с регулярными выражениями, возможно, нет, в зависимости от токенизатора). Затем эти токены должны быть переданы парсеру, который обработает их с помощью правил грамматики, которые определенно не являются регулярными выражениями.
Аксель

53

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

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


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

7
Я работаю в Unix, использую sed, awk & perl и, конечно же, много работаю, но знаю, что когда я использую регулярные выражения, это хак только для записи, который я ненавижу поддерживать. Это хорошо для сценариев оболочки / одноразовых таймеров, но для реальной работы, для всего, что не просто захватывает некоторые данные для сохранения сейчас, я сейчас использую надлежащий токенизатор / лексер / парсер с четким синтаксисом. Мой любимый делает все / любое, чисто + может самооптимизироваться. Я усердно и за многие годы усвоил, что немного самодисциплины в начале означает меньше усилий позже. Регулярное выражение - это мгновение на клавиатуре, а жизнь нахмуриться.
AndrewC

44

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

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

    Современные разработчики программного обеспечения предпочитают разрабатывать код и использовать отладчик для пошагового выполнения и проверки правильности кода. Регулярные выражения не очень хорошо поддерживают этот стиль работы. Один «прогон» регулярного выражения - фактически атомарная операция. Трудно наблюдать пошаговое выполнение в отладчике.

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

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

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


4
Существуют отличные инструменты для отладки регулярных выражений
Джаспер Беккерс,

15
perl -Mre = debug -e "q [aabbcc] = ~ / ab * [cd] /"
Брэд Гилберт

15
Я не думаю, что когда-либо смогу увидеть аббревиатуру "FSM", не думая о Летающем Спагетти-Монстре.
Шаббироб

4
@Shabbyrobe: я не хочу обидеть. При желании вы можете использовать детерминированный конечный автомат (DFA).
Билл Карвин

37

Люди склонны считать регулярные выражения сложными; но это потому, что они используют их неправильно. Написание сложных однострочников без каких-либо комментариев, отступов или именованных снимков. (Вы не помещаете свое сложное выражение SQL в одну строку, без комментариев, отступов или псевдонимов, не так ли?). Так что да, для многих людей это не имеет смысла.

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


2
Ну, разница в том, что в регулярном выражении есть несколько пробелов, а в других языках их нет, и поэтому они, как правило, являются однострочниками (которые иногда переносятся на несколько строк :)
Rado

14
@Rado: Perl, например, имеет xмодификатор для регулярных выражений, который приводит к игнорированию пробелов. Это позволяет поместить регулярное выражение в несколько строк и добавить комментарии.
Натан Феллман

9
Точно так же Python имеет re.Xака re.VERBOSE.
Крейг МакКуин

2
Аналогично xмодификатор в tcl. Я считаю, что это вполне стандартно, поскольку tcl, в отличие от других языков, не использует PCRE.
Slebetman

2
@AndrewC Это одно из самых грубых искажений, которое мог получить этот пост.
Джаспер Беккерс

28

Потому что им не хватает самого популярного инструмента обучения в общепринятых IDE: Regex Wizard не существует. Даже автозаполнение. Вы должны все это кодировать самостоятельно.


3
Тогда вы используете неправильную IDE ... Даже мой текстовый редактор предоставляет подсказки регулярных выражений.
CurtainDog

1
Примечательно, что Expresso и Regex Coach являются очень полезными инструментами для создания регулярных выражений.
Мун,

22
Как в мире вы могли бы автозаполнение регулярного выражения?
AmbroseChapel

3
EditPad Pro имеет подсветку синтаксиса для регулярных выражений в окне поиска, но я нахожу это скорее раздражающим, чем полезным, и держу его выключенным. Но я действительно ценю это, давая мне знать, когда у меня есть непревзойденные скобки; Скобки в частности могут быть медведем, чтобы отслеживать.
Алан Мур

2
@AmbroseChapel - я на пару лет опоздал на эту дискуссию. Но я создал механизм автозаполнения на regexhero.net/tester. Он инициирован общими конструкциями внутри круглых (), квадратных []или фигурных {}скобок. Это также сработает от обратной косой черты.
Стив Уортэм,


16

Я не думаю, что они такие противоречивые.

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

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

http://docs.python.org/howto/regex

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


2
Страница, кажется, переместилась на docs.python.org/howto/regex
Доминик К

@DMan Спасибо. Я отредактирую свой ответ, чтобы отразить.
allyourcode

11

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


7

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

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

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


5

Вы почти можете также спросить о том, почему goto являются спорными.

По сути, когда вы получаете так много «очевидной» силы, люди склонны злоупотреблять ими в ситуациях, для которых они не являются лучшим вариантом. Например, меня поражает количество людей, которые просят разобрать CSV, XML или HTML в регулярных выражениях. Это неподходящий инструмент для работы. Но некоторые пользователи все равно настаивают на использовании регулярных выражений.

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

Обратите внимание, что регулярные выражения по-прежнему могут использоваться для анализа CSV, XML, HTML и т. Д. Но обычно не в одном регулярном выражении.


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

4

Я не думаю, что слово «спорный» является правильным.

Но я видел множество примеров, когда люди говорят: «Какое регулярное выражение мне нужно, чтобы делать такие-то и такие-то манипуляции со строками?» которые являются проблемами XY.

Другими словами, они начали с предположения, что регулярное выражение - это то, что им нужно, но им лучше воспользоваться split (), переводом, подобным tr /// в perl, где символы заменяют друг друга, или просто индекс ().


4

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

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

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

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

4

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

Существует популярная поговорка «Друзья не позволяют друзьям использовать Regex для анализа HTML»

Но что касается меня, я сделал полные HTML-парсеры с использованием Regex, и я считаю, что regex лучше разбирает html-строки как по скорости, так и по памяти (если у вас есть идея, чего вы хотите достичь :))


2
Я думаю, что нечестно списывать большинство разработчиков ... как ленивых. Я бы сказал, что синтаксис очень загадочный, не интуитивный и полный ошибок, для неинициированных, что приводит к высокому барьеру для входа. По той же причине Perl имеет «плохую» репутацию для многих, но также является очень мощным языком. Это все равно что пытаться читать математические выражения, прежде чем вы узнаете символы. Это утомительно, и разработчики должны быть осмотрительными, имея время, чтобы знать, что они получат выгоду от изучения этого синтаксиса.
Katastic Voyage

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

2

Регулярные выражения являются серьезной загадкой для многих людей, включая меня. Это прекрасно работает, но это похоже на математическое уравнение. Я рад сообщить, что кто-то наконец-то создал сводное расположение различных функций регулярных выражений на http://regexlib.com/ . Теперь, если Microsoft создаст только класс регулярных выражений, который автоматически сделает большую часть общих вещей, таких как удаление писем или фильтрация дат.


2
Вы упускаете суть. Идея регулярных выражений состоит в том, что вы тратите некоторое время на их изучение, и когда вы закончите, вам больше не понадобится какой-то волшебный класс «прочитайте дату». Вместо этого им требуется очень мало усилий для регулярных выражений. Более того, для написания единицы для «гггг / мм / дд» потребуется столько же усилий, сколько для написания единицы для «мм-дд-гггг», или даже для «мм-гггг / дд» (которая выиграла это часто случается, но это пример того, как вы можете делать то, чего никогда не сможет волшебный класс ").
Джаспер

1

Я нахожу регулярные выражения неоценимыми время от времени. Когда мне нужно сделать несколько «нечетких» поисков и, возможно, заменить. Когда данные могут отличаться и иметь определенную случайность. Однако, когда мне нужно выполнить простой поиск и заменить или проверить строку, я не использую регулярные выражения. Хотя я знаю многих людей, которые делают это, они используют это для всего. Это противоречие.

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

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


0

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


Чем отличаются реализации регулярных выражений в подходе к максимальному соответствию, то, что я думаю, вы называете «жадностью»? Вы имеете в виду разницу между самой левой-самой длинной и самой левой- самой левой семантикой? Это единственное различие, о котором я знаю; то есть ли жадность превосходит рвение или наоборот .
tchrist

0

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

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


0

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


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

Я думаю, ваш менеджер не знает, что «настоящий герой программирования - тот, кто пишет отрицательный код».
Раджив

Если ваш менеджер собирается поблагодарить вас за выполнение работы с 3 строками кода (включая регулярные выражения), а также похвалить какого-нибудь сотрудника Doofus, который сделал это в 900 строках Ассемблера ... Я предлагаю найти новую работу.
Фил Перри

0

Приличные системы регулярных выражений, такие как используемые в lex и yacc для определения компилятора, хороши, очень полезны и чисты. В этих системах типы выражений определяются в терминах других. Это отвратительные искаженные нечитаемые гигантские однострочные регулярные выражения с линейным шумом, которые обычно встречаются в кодах perl и sed (и т. Д.), Являются «спорными» (мусор).


-4

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

Это хорошее применение.

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

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

Многие ситуации требуют именно регулярных выражений и ничего больше.

Замена специальных непечатаемых символов безобидными символами - еще одно хорошее применение.

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


10
Опыт показывает, что регулярные выражения на самом деле довольно плохой инструмент для проверки формата адресов электронной почты. Действительно полный валидатор формата, реализованный как регулярное выражение, является чудовищем из нескольких сотен символов, в то время как большинство более коротких «достаточно хороших» валидаторов, которые большинство людей тратят на создание 5 минут, будут отклонять большие категории действительных, доставляемых адресов.
Дейв Шерохман

Я слышал, чувак. Я говорил о «достаточно хорошо», и хотя теоретически большие полосы могут быть большими, рассмотрите процент охвата, который вы получаете в таком коротком выражении. Я тоже видел чудовище, но какова твоя изящная альтернатива?
Крис Морли

2
Я использовал что-то вроде \ w @ \ w +. \ W +, чтобы быстро найти адрес электронной почты в огромном каталоге файлов, где важна скорость, а несколько ложных срабатываний или ложных отрицаний не имели значения. Но лучший способ проверить адрес электронной почты, кажется, это отправить письмо на него.
RossFabricant

Да, адрес электронной почты: спецификация адреса - неприятный беспорядок stackoverflow.com/questions/611775/…
Ник Ван Брант

@Nick, @Dave: проверка почтового адреса не должна быть неприятной.
2010 года
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.