Альтернативы регулярным выражениям

У меня есть набор строк с введенными в них числами. Они выглядят как /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).
  • Поддерживает '|' а также. Таким образом, выражение '/cal/(long | short)/3/4/' будет соответствовать '/cal/long/3/4/1: 2', а также '/cal/short/3/4/1: 2.
  • Доступна ли реализация Java или будет легко реализована на Java.

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

Спасибо!

Ответ 1

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

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

http://java-source.net/open-source/parser-generators

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

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

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

Ответ 2

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

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

Ответ 3

Ограничение Java является серьезным. Я бы рекомендовал использовать компиляторы синтаксического анализа, но вам нужно будет перевести идеи на Java, используя классы вместо функций. На эту тему доступно много и много статей; одним из самых простых для подхода является Функции более высокого порядка Graham Hutton для анализа. Хаттон подход делает его особенно легко решить, чтобы преуспеть или потерпеть неудачу на основе таких условий, как величина числа, как показано в вашем примере.

Ответ 4

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

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

Ответ 5

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

Ответ 7

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

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