Кажется, что выбор использования синтаксического анализа строк и регулярных выражений у меня возникает регулярно каждый раз, когда возникает ситуация, когда мне нужна часть строки, информация об указанной строке и т. д.
Причина, по которой это возникает, заключается в том, что мы оцениваем действие заголовка мыла, после, он был проанализирован во что-то управляемое через объект OperationContext для WCF и тогда, принимающий решения по этому поводу. Прямо сейчас простое решение кажется базовым подстроками, чтобы упростить реализацию, но часть меня задается вопросом, будет ли RegEx лучше или надежнее. Другая часть меня задается вопросом, будет ли это похоже на использование дробовика, чтобы убить муху в нашем конкретном сценарии.
Поэтому я должен спросить, каков типичный порог, который люди используют, когда пытаются решить использовать RegEx вместо обычного синтаксического анализа строк. Обратите внимание, что я не очень силен в регулярных выражениях, и из-за этого я стараюсь уклоняться, если только это не является абсолютно необходимым, чтобы избежать большего количества сложностей, чем мне нужно.
Если вы не могли сказать по моему выбору сокращений, это относится к .NET (C#), но я считаю, что это не имеет большого отношения к вопросу.
РЕДАКТИРОВАТЬ: Судя по моему типичному обаянию Raybell, я был слишком многословен или вводил в заблуждение в своем вопросе. Я хочу извиниться. Я давал некоторую предысторию, чтобы помочь понять, что я делаю, а не вводить людей в заблуждение.
Я в основном ищу руководство относительно того, когда использовать подстроку и ее варианты вместо регулярных выражений и наоборот. И хотя в некоторых ответах это могло быть упущено (и опять же, по моей вине), я искренне их оценил и проголосовал соответственно.
Это близко к тому, что я искал. Я искал, но не нашел ничего, что я считал подходящим, хотя это кажется очень близким.
Думаю, я спрашиваю, дает ли этот вопрос вам информацию, которую вы искали?
Вроде, но похоже, что у меня есть лучший ответ ниже, и я, вероятно, скоро его приму.





Регулярное выражение может быть
В некоторых ситуациях все эти преимущества могут быть достигнуты с помощью регулярного выражения, в других достигаются только некоторые (например, регулярное выражение непросто понять), а в других ситуациях регулярное выражение труднее понять, запутывает намерение, дольше и трудно изменить.
Чем больше этих (и, возможно, других) преимуществ я получаю от регулярного выражения, тем больше вероятность, что я их использую.
Возможное практическое правило: если понимание регулярного выражения потребует нескольких минут для кого-то, кто в некоторой степени знаком с регулярными выражениями, вы не хотите его использовать (если только «нормальный» код не является еще более запутанным ;-).
Хм ... все еще нет простого практического правила, извините.
Когда необходимое преобразование не является простым, но все же концептуально простым.
нет причин вытаскивать Regex, если вы, например, выполняете замену прямой строки ... проще просто использовать строку.
с другой стороны, сложное правило со многими условными выражениями или особыми случаями, которые занимают более 50 символов регулярного выражения, может стать кошмаром для дальнейшего использования, если вы явно не выпишете его
Я бы всегда использовал регулярное выражение, если это не что-то простое очень, например разделение строки, разделенной запятыми. Если я думаю, что когда-нибудь строки могут стать более сложными, я, вероятно, начну с регулярного выражения.
Я не согласен с мнением, что регулярные выражения сложны или сложны. Это один из инструментов, который каждый разработчик должен изучить и хорошо изучить. У них есть множество применений, и, как только вы научитесь, это именно то, о чем вам больше никогда не придется беспокоиться.
Регулярные выражения редко бывают излишними - если совпадение простое, то и регулярное выражение тоже.
Даже то, что парсер CSV обманчиво сложно написать, учитывая правила цитирования. (Символы новой строки и запятые могут встречаться в одном поле, если поле заключено в кавычки.) Не недооценивайте скромный CSV !!! Даже с регулярным выражением действительно сложно правильно разобрать: o)
Я сказал строку, разделенную запятыми, а не файл CSV. Я бы никогда не рекомендовал ничего, кроме специальной библиотеки или парсера для CSV-файла. Я на самом деле написал парсер C++ CSV, который справился со всем вышеперечисленным, но мой отец был DFA
[W]e're evaluating a soap header's action and making decisions on that
Никогда не используйте регулярные выражения или базовый синтаксический анализ строк для обработки XML. Каждый язык, который сейчас широко используется, имеет отличную поддержку XML. XML - это обманчиво сложный стандарт, и маловероятно, что ваш код будет правильным в том смысле, что он будет правильно анализировать весь правильно сформированный ввод XML, и даже если это так, вы зря тратите свое время, потому что (как только что упоминалось) каждый язык в общее использование имеет поддержку XML. Использовать регулярные выражения для синтаксического анализа XML - непрофессионально.
Чтобы ответить на ваш вопрос, в целом следует минимизировать использование регулярных выражений, поскольку они не очень удобочитаемы. Часто вы можете комбинировать синтаксический анализ строк и регулярные выражения (возможно, в цикле), чтобы создать гораздо более простое решение, чем одни только регулярные выражения.
Я здесь как бы ввел в заблуждение, и прошу прощения. Реальность такова, что к тому времени, когда мы возимся с этим, он был проанализирован для нас через OperationContext. Я благодарю вас за то, что вы указали на это!
Я немного обновил вопрос, чтобы улучшить ясность, но мне кажется, что он все еще сбивает с толку. Я его немного переделаю, когда у меня будет больше времени. Я прошу прощения.
Простите. Я, наверное, мог бы быть более вежливым, но это то, что сводит меня с ума каждый раз, когда я это вижу.
О, не беспокойтесь! Я здесь с тобой. Есть подходящий инструмент для правильной работы. Мне не нужно воссоздавать колесо или парсер, как бы то ни было.
Моя основная рекомендация - использовать регулярные выражения для одноразового кода и для проверки пользовательского ввода. Или когда я пытаюсь найти определенный узор в большом фрагменте текста. Для большинства других целей я напишу грамматику и реализую простой синтаксический анализатор.
Одно важное правило (которое действительно трудно обойти, хотя я вижу, что люди все время стараются) - всегда использовать синтаксический анализатор в тех случаях, когда грамматика целевого языка рекурсивна.
Например, рассмотрим крошечный «язык выражений» для вычисления арифметических выражений в скобках. Примеры «программ» на этом языке будут выглядеть так:
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 с помощью регулярных выражений, и это БЕЗУМНО. Объекты JSON рекурсивны, поэтому они просто просят обычных грамматик и рекурсивных анализаторов спуска.
Хммммммм ... Глядя на ответы других людей, мне кажется, что я ответил не на тот вопрос.
Я интерпретировал это как «когда следует использовать простое регулярное выражение, а не полноценный синтаксический анализатор?» в то время как большинство людей, кажется, интерпретировали вопрос как «когда вы должны использовать свою неуклюжую специальную схему посимвольной проверки, а не использовать регулярное выражение?»
Учитывая эту интерпретацию, мой ответ: никогда.
Хорошо .... еще одно редактирование.
Я буду немного снисходительнее к схеме «рулонись сам». Только ... не называйте это "парсингом": 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.
Регулярные выражения действительно не так уж и сложно выучить. По сравнению с огромным полнофункциональным языком, таким как C#, с десятками ключевых слов, примитивных типов и операторов, а также стандартной библиотекой с тысячами классов, регулярные выражения абсолютно просты. Большинство реализаций регулярных выражений поддерживают около десятка операций (плюс-минус).
Вот отличная ссылка:
http://www.regular-expressions.info/
PS: В качестве бонуса, если вы когда-нибудь захотите научиться писать свои собственные парсеры (с lex / yacc, ANTLR, JavaCC или другими подобными инструментами), изучение регулярных выражений - отличная подготовка, потому что инструменты генератора парсеров используют многие из те же принципы.
У меня создалось впечатление, что «базовый анализ строки» подразумевает такие вещи, как 1 вызов .indexOf () и 2 .subString () или что-то подобное. Для таких сложных вещей я бы определенно выбрал путь парсера.
Я не обязательно выполняю посимвольную проверку. Я просто хочу захватить подстроку, а затем действовать в соответствии с ней. В общем, я ищу общие рекомендации по выбору подстроки вместо регулярного выражения. Я полагаю, что, возможно, я не очень ясно выразился в своем вопросе ...
Итак, из всех, с учетом вашего недавнего редактирования, это в основном то, что я искал. Спасибо!
Рад, что смог (в конечном итоге) помочь!
Что касается вас в целом с "настоящим парсером" - почему люди так боятся грамматики?
Хороший вопрос. Я думаю, что большинству разработчиков удобнее изучать новую технологию, которая поставляется с инструкциями (например, «spring» или «javascript»), чем изучать новый набор абстрактных понятий (например, «синтаксический анализ» или «машинное обучение»).
(... продолжение ...) Для меня все наоборот. Мне становится скучно читать бесконечную документацию по API из огромных корпоративных фреймворков, но я действительно увлечен решением сложных проблем с помощью новых концепций, алгоритмов и математических приемов. Я считаю себя скорее «специалистом по CS», чем «инженером-программистом».
Что касается парсеров, не могли бы вы порекомендовать один из этих инструментов в качестве хорошей отправной точки? Можно было бы предположить, что я сделал кое-какие элементарные вещи, но никогда особо не вдавался в подробности.
В Java мой любимый инструмент - JavaCC. Его довольно легко изучить (если у вас есть фон с регулярными выражениями), и он также довольно мощный. Но для других платформ (или для поддержки нескольких платформ) вы не можете победить ANTLR. Это несколько сложнее и труднее в освоении, но это мощный В самом деле.
Я согласен с тем, что сказал Бенджисмит, но хочу немного уточнить. Для очень простых синтаксисов может хорошо работать базовый синтаксический анализ строк, но и регулярные выражения. Я бы не назвал их излишеством. Если работает, значит работает - выбирайте то, что считаете самым простым. А для среднего и среднего разбора строк обычно подходит регулярное выражение.
Однако, как только вы начнете определять грамматику, то есть сложный синтаксический анализ строк, как можно скорее вернитесь к использованию какого-либо конечного автомата или тому подобного. Регулярные выражения просто плохо масштабируются, если использовать этот термин. Они становятся сложными, трудно интерпретируемыми и даже неспособными.
Я видел по крайней мере один проект, в котором использование регулярных выражений продолжало расти и расти, и вскоре у них возникли проблемы с добавлением новых функций. Когда, наконец, пришло время выпустить новый основной выпуск, они сбросили все регулярные выражения и пошли по пути синтаксического анализатора грамматики.
В одном случае здесь я видел, как регулярное выражение фактически рекурсивно повторяет цикл с правильным вводом. Увеличили серверные процессоры и позволили DOS занять место. Излишне говорить, что я очень осторожен, когда вижу, что они выступают в качестве решения именно по этой причине.
Я бы подумал, что самый простой способ узнать, когда использовать регулярные выражения, а когда нет, - это когда для строкового поиска требуется инструкция IF / THEN или что-то похожее на ту или иную логику, тогда вам нужно что-то лучше, чем простое сравнение строк, которое регулярное выражение светится.
Если вы не скажете иначе, я думаю, что этот вопрос отвечает на тот же вопрос, который задаете вы: stackoverflow.com/questions/56342/…