Моим основным правилом является использование регулярных выражений для одноразового кода и для проверки пользовательского ввода. Или когда я пытаюсь найти определенный шаблон в большой части текста. Для большинства других целей я напишу грамматику и реализую простой парсер.
Одна важная рекомендация (от которой трудно обойтись, хотя я вижу, что люди все время пытаются это сделать) - всегда использовать парсер в случаях, когда грамматика целевого языка является рекурсивной.
Например, рассмотрим крошечный «язык выражений» для оценки заключенных в скобки арифметических выражений. Примеры «программ» на этом языке выглядят так:
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 или других подобных инструментов), изучение регулярных выражений является отличной подготовкой потому что инструменты генератора парсеров используют многие из тех же принципов.