Как лучше всего разбирать строки?

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

Нам также нужно будет поддерживать больше «форматов» в будущем.

Пойдем ли мы за решением, используя:

  • Регулярное выражение
  • Простой поиск по строке (с использованием string.IndexOf и т. д.)
  • Lex / Yacc
  • Другой

Общее решение будет разработано на C# 2.0 (надеюсь, 3.5).

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
1 238
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Regex.

Regex может решить почти все, кроме мира во всем мире. Ну, может быть, и мир во всем мире.

Я слышал, что Regex был ответственен за падение Берлинской стены.

Robert Durgin 11.09.2008 15:53

Им действительно следует прекратить использовать ядерное оружие в фильмах-катастрофах.

Coincoin 11.09.2008 16:19

Regex: причина и решение всех проблем в жизни.

Matthew King 22.06.2010 10:51

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-е место.

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

Geek 06.05.2009 13:49

Другие вопросы по теме