У нас есть сценарий, который требует от нас синтаксического анализа большого количества сообщений электронной почты (обычного текста), причем каждый «тип» электронной почты является результатом выполнения сценария на различных платформах. Некоторые из них разделены табуляцией, некоторые - пробелами, а о некоторых мы просто еще не знаем.
Нам также нужно будет поддерживать больше «форматов» в будущем.
Пойдем ли мы за решением, используя:
Общее решение будет разработано на C# 2.0 (надеюсь, 3.5).





Regex.
Regex может решить почти все, кроме мира во всем мире. Ну, может быть, и мир во всем мире.
Им действительно следует прекратить использовать ядерное оружие в фильмах-катастрофах.
Regex: причина и решение всех проблем в жизни.
Regex, вероятно, будет для вас лучшим выбором, испытанным и проверенным. Кроме того, можно скомпилировать регулярное выражение.
Вероятно, у вас должна быть подключаемая система, независимо от того, какой тип синтаксического анализа строк вы используете. Итак, эта система вызывает нужный «плагин» в зависимости от типа электронного письма для его анализа.
Имея как можно меньше информации, которую вы предоставили, я бы выбрал Regex.
Но то, какую информацию вы хотите проанализировать и что вы хотите сделать, может изменить решение на Lex / Yacc ..
Но похоже, что вы уже определились с поиском по строкам :)
Каждое из трех указанных вами решений охватывает очень разные потребности.
Разбор вручную (простой текстовый поиск) является наиболее гибким и адаптируемым, однако он очень быстро становится настоящей головной болью, поскольку требуемый синтаксический анализ более сложен.
Регулярное выражение - это золотая середина и, вероятно, ваш лучший выбор здесь. Они мощные, но гибкие, так как вы сами можете добавить больше логики из кода, который вызывает другое регулярное выражение. Главный недостаток здесь - скорость.
Lex / Yacc действительно адаптирован только к очень сложным, предсказуемым синтаксисам и не имеет большой гибкости после компиляции. Вы не можете легко изменить синтаксический анализатор в середине синтаксического анализа, ну, на самом деле вы можете, но он слишком тяжелый, и вам лучше использовать вместо него регулярное выражение.
Я знаю, что это клише отвечать, все действительно сводится к вашим точным потребностям, но из того, что вы сказали, я лично, вероятно, выбрал бы пакет регулярных выражений.
В качестве альтернатива, как заметил Вайбхав, если у вас есть несколько различных ситуаций, которые могут возникнуть, и вы можете легко определить, какая из них происходит, вы можете создать систему плагинов, которая выбирает правильный алгоритм, и все эти алгоритмы могут быть очень разными, один использует Lex / Yacc в заостренных случаях, а другой использует IndexOf и регулярное выражение для более простых случаев.
Лучше всего использовать RegEx, потому что он обеспечивает гораздо большую гибкость, чем любой из других вариантов.
Хотя вы можете использовать IndexOf для обработки чего-либо, вы можете быстро обнаружить, что пишете код, который выглядит так:
if (s.IndexOf("search1")>-1 || s.IndexOf("search2")>-1 ||...
Это можно сделать с помощью одного оператора RegEx. Кроме того, есть много мест, таких как RegExLib.com, где вы можете найти людей, которые используют регулярные выражения для решения проблем.
Вы должны спроектировать свое решение так, чтобы его можно было обновлять, чтобы вы могли справляться с неизвестными ситуациями, когда они возникают. Создайте интерфейс для парсеров, который содержит не только методы для синтаксического анализа писем и возврата результатов в стандартном формате, но и для изучения электронного письма, чтобы определить, будет ли анализатор выполняться.
В своей конфигурации определите тип анализатора, который вы хотите использовать, установите его параметры конфигурации и конфигурацию идентификаторов, которые определяют, будет ли анализатор действовать или нет. Назовите анализаторы по имени сборки, чтобы типы могли быть созданы во время выполнения, даже если нет статических ссылок на их сборки.
Идентификаторы также могут реализовывать интерфейс, поэтому вы можете создавать разные типы, которые проверяют разные вещи. Например, вы можете создать идентификатор регулярного выражения, который анализирует электронную почту по определенному шаблону. Убедитесь, что для идентификатора доступно как можно больше информации, чтобы он мог принимать решения, например, по адресам, а также по содержанию электронной почты.
Если известные вам парсеры не могут обработать задание, создайте новую DLL с типами, реализующими синтаксический анализатор и интерфейсы идентификатора, которые могут обрабатывать задание, и поместите их в каталог bin.
Это зависит от того, что вы разбираете. Для всего, что выходит за рамки того, что может обрабатывать Regex, я использовал ANTLR. Прежде чем вы впервые перейдете к синтаксическому анализу с рекурсивным спуском, я бы исследовал, как они работают, прежде чем пытаться использовать фреймворк, подобный этому. Если вы подписаны на журнал MSDN, проверьте выпуск за февраль 2008 г., где есть статья о написании журнала с нуля.
Как только вы поймете, изучать ANTLR станет намного проще. Существуют и другие фреймворки, но ANTLR, похоже, пользуется наибольшей поддержкой сообщества и общедоступной документацией. Автор также опубликовал Окончательный справочник по ANTLR: создание предметно-ориентированных языков.
@Coincoin покрыл основы; Я просто хочу добавить, что с регулярным выражением особенно легко получить трудный для чтения и поддержки код. Regex - мощный и очень компактный язык, поэтому часто так и происходит.
Использование пробелов и комментариев в регулярном выражении может существенно облегчить поддержку регулярных выражений. Эрик Ганнерсон натолкнул меня на эту идею. Вот пример.
Используйте PCRE. Все остальные ответы - только 2-е место.
Он позволяет вам выполнять различные типы поиска по тексту, регулярным выражениям и т. д. Это скомпилированная библиотека, которая позволяет вам делать так много вещей на многих платформах и проверена годами. Вероятно, это будет намного быстрее, чем реализация, которую вы напишете.
Я слышал, что Regex был ответственен за падение Берлинской стены.