Когда лучше использовать регулярные выражения над базовым разбиением / подстрокой строк? - PullRequest
18 голосов
/ 11 декабря 2008

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

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

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

Если вы не можете сказать по моему выбору сокращений, это в .NET land (C #), но я считаю, что это не имеет большого отношения к вопросу.


РЕДАКТИРОВАТЬ : Кажется, в соответствии с моим типичным заклинанием Рэйбелл, я был слишком многословным или вводящим в заблуждение в моем вопросе. Я хочу извиниться. Я давал некоторые сведения, чтобы помочь понять, что я делаю, а не вводить людей в заблуждение.

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

Ответы [ 7 ]

22 голосов
/ 11 декабря 2008

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

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

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

1 + 2
5 * (10 - 6)
((1 + 1) / (2 + 2)) / 3

Грамматику легко написать, и она выглядит примерно так:

DIGIT := ["0"-"9"]
NUMBER := (DIGIT)+
OPERATOR := ("+" | "-" | "*" | "/" )
EXPRESSION := (NUMBER | GROUP) (OPERATOR EXPRESSION)?
GROUP := "(" EXPRESSION ")"

С помощью этой грамматики вы можете быстро создать парсер рекурсивного спуска.

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

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


Хммммм ... Глядя на ответы других людей, я думаю, что мог ответить не на тот вопрос.

Я интерпретировал это как "когда следует использовать использовать регулярное выражение, а не полноценный парсер?" тогда как большинство людей, по-видимому, интерпретировали вопрос как «когда вы должны использовать собственную неуклюжую специальную схему посимвольной проверки символов вместо использования регулярного выражения?»

С учетом этой интерпретации мой ответ: никогда.


Хорошо ... еще одно редактирование.

Я буду немного прощать схему самокрутки. Просто ... не называйте это "разбором": о)

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

if (str.equals("DooWahDiddy")) // No problemo.

if (str.contains("destroy the earth")) // Okay.

if (str.indexOf(";") < str.length / 2) // Not bad.

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

if (str.startsWith("I") && str.endsWith("Widget") &&
    (!str.contains("Monkey") || !str.contains("Pox")))  // Madness.

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

Вот отличная ссылка:

http://www.regular -expressions.info /

PS: В качестве бонуса, если вы когда-либо делаете хотите узнать о написании ваших собственных синтаксических анализаторов (с помощью lex / yacc, ANTLR, JavaCC или других подобных инструментов), изучение регулярных выражений является отличной подготовкой потому что инструменты генератора парсеров используют многие из тех же принципов.

6 голосов
/ 11 декабря 2008

регулярное выражение может быть

  • легче понять
  • более четко выразить намерение
  • намного короче
  • проще изменить / адаптировать

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

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

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

Хм ... простое эмпирическое правило, извините.

2 голосов
/ 11 декабря 2008

[W] мы оцениваем заголовки мыла действия и принятие решений на этом

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

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

1 голос
/ 11 декабря 2008

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

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

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

1 голос
/ 11 декабря 2008

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

нет причин вытягивать Regex, если вы делаете прямую замену строки, например ... проще просто использовать строку. Замена

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

0 голосов
/ 11 декабря 2008

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

0 голосов
/ 11 декабря 2008

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

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

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

...