Подтвердить что ты не робот

Когда лучше использовать регулярные выражения для базового строкового разделения/подстроки?

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

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

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

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


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

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

Надеюсь, это поможет некоторым.

4b9b3361

Ответ 1

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

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

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

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

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

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

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

Эквивалентное регулярное выражение ДЕЙСТВИТЕЛЬНО трудно писать, поскольку регулярные выражения обычно не имеют очень хорошей поддержки для рекурсии.

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


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

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

Учитывая эту интерпретацию, мой ответ: никогда.


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

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

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

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

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

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

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

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

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

Здесь отличная ссылка:

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

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

Ответ 2

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

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

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

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

Возможное эмпирическое правило: если понимание регулярного выражения займет несколько минут для тех, кто знаком с регулярными выражениями, то вы не хотите его использовать (если только "нормальный" код еще более запутан; /p >

Hm... все еще нет простого правила большого пальца, извините.

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Ответ 7

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