Альтернативы регулярным выражениям - PullRequest
11 голосов
/ 05 февраля 2009

У меня есть набор строк с числами, встроенными в них. Они выглядят примерно так: / cal / long / 3/4/145: 999 или / pa / metrics / CosmicRay / 24: 4: bgp: EnergyKurtosis. Я хотел бы иметь синтаксический анализатор выражений,

  • Простота в использовании. Учитывая несколько примеров, кто-то должен быть в состоянии сформировать новое выражение. Я хочу, чтобы конечные пользователи могли формировать новые выражения для запроса этого набора строк. Некоторые из потенциальных пользователей - инженеры-программисты, другие - тестировщики, а некоторые - ученые.
  • Позволяет ограничения по числам. Что-то вроде '/ cal / long / 3/4/143: #> 100 & <1110', чтобы указать, что префикс строки с '/ cal / long / 3/4/143:', а затем число между (100,1110) ожидается. </li>
  • Поддерживает '|' и . Таким образом, выражение '/ cal / (long | short) / 3/4 / ' будет соответствовать '/ cal / long / 3/4/1: 2', а также '/ cal / short / 3/4 / 1: 2'
  • Имеет реализацию Java или может быть легко реализована в Java.

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

Спасибо!

Ответы [ 7 ]

7 голосов
/ 05 февраля 2009

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

Если вы найдете или создадите какой-нибудь альтернативный язык синтаксического анализа, который охватывает только подмножество возможностей, которые может использовать Regex, у вас быстро будет пользователь, запрашивающий концепцию, которая может быть выражена в Regex, но ваш вкус просто не учитывается. Потратьте свое время на решение проблем, которые еще не были решены!

4 голосов
/ 05 февраля 2009

Ограничение Java является строгим. Я бы рекомендовал использовать парсинг-комбинаторы , но вам придется переводить идеи в Java, используя классы вместо функций. Есть много, много статей на эту тему; Функции высшего порядка для синтаксического анализа Грэма Хаттона *1003*. Подход Хаттона позволяет особенно легко решить, добиться успеха или потерпеть неудачу, исходя из таких условий, как величина числа, как показано в вашем примере.

4 голосов
/ 05 февраля 2009

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

Возможно, вы захотите рассмотреть генератор парсера - такие вещи, как классический lex и yacc. Я не очень знаком с выбором Java, но вот список:

http://java -source.net / с открытым исходным кодом / СА-генераторы

Если вы не знакомы, стандартным подходом было бы сначала создать лексер , который превращает ваши строки в токены. Затем вы передадите эти токены в парсер, который применяет к ним вашу грамматику и выдает какой-то результат.

В вашем случае я предполагаю, что синтаксический анализатор приведет к комбинации регулярного выражения и дополнительных условий. Для вашего примера числового ограничения он может дать вам регулярное выражение \/cal/long/3/4/143:(\d+)\ и ограничение для применения к первой группировке (часть \d+), которая требует, чтобы число лежало между 100 и 1100. Затем вы примените RE к вашим строкам для кандидатов и примените ограничение к этим кандидатам, чтобы найти совпадения.

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

2 голосов
/ 05 февраля 2009

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

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

0 голосов
/ 15 апреля 2013

Если вы собираетесь идти по пути парсера, проверьте систему разбора GOLD. Часто это лучший вариант, чем что-то вроде YACC, более чистый, чем чистые регулярные выражения, и поддерживает Java.

http://goldparser.org/about/how-it-works.htm

0 голосов
/ 23 января 2010

http://java -source.net / open-source / parser-generators и http://catalog.compilertools.net/java.html содержат каталоги инструментов для этого. Сравните также вопрос stackoverflow Как я могу разобрать код для построения компилятора в Java? .

0 голосов
/ 05 февраля 2009

На самом деле вы описали Java Pattern Matcher. Который как раз использует Regex в качестве языка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...