Действительно ли регулярны регулярные выражения? - PullRequest
17 голосов
/ 30 сентября 2008

Любой код, который я видел, который использует регулярные выражения, обычно использует их как черный ящик:

  1. положить в строку
  2. Волшебное регулярное выражение
  3. Выйти строка

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

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

Ответы [ 20 ]

27 голосов
/ 30 сентября 2008

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

Множество реализаций регулярных выражений позволяют дополнять регулярные выражения пробелами и комментариями.
См. http://www.regular -expressions.info / comments.html
и ужас кодирования: Регулярные выражения: теперь у вас две проблемы

Любой код, который я видел и использует регулярные выражения, обычно использует их как черный ящик:

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

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

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

Редактировать: пожалуйста, прочитайте комментарий Джеффа к этому ответу о производственном коде.

14 голосов
/ 30 сентября 2008

Обязательно.

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

8 голосов
/ 30 сентября 2008

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

$foo =~ m{
    (some-thing)          # matches something
    \s*                   # matches any amount of spaces
    (match another thing) # matches something else
}x;

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

7 голосов
/ 30 сентября 2008

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

Замените регулярное выражение на "C" или "C #", или "Java", или "Python", или "Perl", или "SQL", или "Ruby", или "awk", или ... что-нибудь, действительно, и вы получите то же самое вопрос.

Regex - это просто другой язык, кодированный Хаффманом , чтобы быть эффективным при сопоставлении строк. Подобно Java, Perl, PHP или особенно SQL, каждый язык имеет свои сильные и слабые стороны, и вам нужно знать язык, на котором вы пишете, когда вы его пишете (или поддерживаете), чтобы иметь какую-то надежду на продуктивность.

Редактировать: Майк, регулярные выражения Хаффмана закодированы в том, что общие дела короче, чем редкие вещи. Буквенные совпадения текста, как правило, представляют собой один символ (тот, который вы хотите сопоставить). Существуют специальные символы - общие из них короткие. Специальные конструкции, такие как (? :) длиннее. Это не то же самое, что было бы распространено в языках общего назначения, таких как Perl, C ++ и т. Д., Поэтому кодирование Хаффмана было нацелено на эту специализацию.

7 голосов
/ 30 сентября 2008

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

6 голосов
/ 30 сентября 2008

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

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

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

3 голосов
/ 30 сентября 2008

Регулярные выражения - НЕ ЕДИНСТВЕННЫЙ способ что-то сделать. Вы можете делать в коде логически все, что может делать регулярное выражение. Регулярные выражения просто

  1. Fast
  2. Протестировано и проверено
  3. Мощный
3 голосов
/ 16 октября 2008

RegExs могут быть очень обслуживаемыми, если вы используете новые функции, представленные Perl 5.10. Функции, на которые я ссылаюсь - это функции с обратным портированием Perl 6.

Пример скопирован напрямую из perlretut .

Определение именованных шаблонов

Некоторые регулярные выражения используют идентичные подшаблоны в нескольких местах. Начиная с Perl 5.10, можно определить именованные подшаблоны в разделе шаблона, чтобы их можно было вызывать по имени в любом месте шаблона. Этот синтаксический шаблон для этой группы определений (?(DEFINE)(?<name>pattern)...). Вставка именованного шаблона записывается как (?&name).

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

/^
  (?&osg)\ * ( (?&int)(?&dec)? | (?&dec) )
        (?: [eE](?&osg)(?&int) )?
 $
 (?(DEFINE)
     (?<osg>[-+]?)         # optional sign
     (?<int>\d++)          # integer
     (?<dec>\.(?&int))     # decimal fraction
 )
/x
2 голосов
/ 30 сентября 2008

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

Для пользователей .NET может существовать библиотека " Linq to RegEx ", которая выглядит хуже или " Библиотека читаемых регулярных выражений " Это делает их более простыми в обслуживании и в то же время проще в написании. Я использовал оба из них в своих собственных проектах. Я знал, что html-исходный код, который я проанализировал с ними, может измениться в любое время.

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

2 голосов
/ 30 сентября 2008

регулярные выражения способ делать вещи? Это зависит от задачи.

Как и во всем программировании, нет точного и быстрого правильного или неправильного ответа.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...