2012-05-23 2 views
6

Я ищу способ упростить регулярное выражение, которое состоит из значений (например, 12345), знаки отношения (<,>, < =,> =) и junctors (&,!). Например. выражение:Упростить сложное регулярное выражение

>= 12345 & <=99999 & !55555 

должно быть сопоставлено. У меня есть это регулярное выражение:

(^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 

Я особенно недоволен повторением < =,> =, <,> в начале и в конце выражения. Я был бы рад получить подсказку, как сделать его проще, например. смотрите вперед, оглянитесь назад.

+0

что бы вы хотели, чтобы результат был? –

+0

Пожалуйста, покажите несколько совпадений и результатов, и, возможно, некоторые примеры несоответствий. Это поможет нам понять, что вы хотите сделать. – kevlar1818

+0

Если выражение может быть произвольной длины, тогда вы можете сделать что-то более практическое, чем регулярные выражения, иначе оно станет довольно уродливым и трудным для чтения. – kevin628

ответ

0

Вы можете сделать все пробелы необязательными (с вопросительными знаками), поэтому вам не нужно явно перечислять все возможности. Также вы можете группировать символы равенства/неравенства в наборе символов ([]).

Как это, я думаю,

(^[<>]=?\s?)((!|)([0-9]{1,5}))(\s?&\s?[<>]=?\s|$)* 
+0

Это будет соответствовать '=', не говоря уже о '> = <', '>>', '==>' и т. Д. – kevlar1818

+0

@ kevlar1818: Правильно, но могут ли они произойти? [<>] =? действительно лучше, отредактировано. – Junuxx

+0

Отказ от появления узоров (какими бы невероятными ни был рисунок) не является хорошим регулярным выражением. – kevlar1818

0

Как насчет

[<>]=?|\d{1,5}|[&!\|]

, который заботится о вашей> /> =/</< = повторение. Кажется, работает для меня.

Сообщите мне, если это отвечает на ваш вопрос или нуждается в работе.

+0

Nice one @ kevlar1818. Но он не поймает также «> = <= 12345 & <= 99999 &! 55555». Хотим ли мы, чтобы он поймал подобные примеры? – Zecas

+0

Я предлагаю усилить ваш ответ с помощью '(([<>] =? |!) \ S * \ d {1,5} \ s *) (& \ s + ([<>] =? |!) \ S * \ д {1,5} \ S *) * '. Как вы думаете, @ kevlar1818? – Zecas

0

У меня есть двухэтапная процедура. Сначала перейдите на юнкер, затем проверьте отдельные детали.

final String expr = ">= 12345 & <=99999 & !55555".replaceAll("\\s+", ""); 
for (String s : expr.split("[|&]")) 
    if (!s.matches("([<>]=?|=|!)?\\d+")) { System.out.println("Invalid"); return; } 
System.out.println("Valid"); 

Но мы все еще оставляем догадываемся, говоришь ли вы о валидации или чем-то еще.

0

Вы, кажется, тратите много сил на дополнительные места. что-то вроде \s? (0 - 1) или \s* (0 - много) было бы лучше.

также повторяющиеся элементы, разделенные чем-то, всегда сложны. лучше всего сделать регулярное выражение для «вещи», чтобы упростить повторение.

limit = '\s*([<>]=?|!)\s*\d{1,5}\s*' 
one_or_more = '^' + limit + '(&' + limit + ')*$' 

или расширены из:

^\s*([<>]=?|!)\s*\d{1,5}\s*(&\s*([<>]=?|!)\s*\d{1,5}\s*)*$ 

также ! является "отношение знак", а не "юнктор", если я правильно понять.

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

0

Это то, что вы хотите:

^(\s*([<>]=?)?\s*!?\d{1,5}\s*(&|$))* 

Эти объяснения подразделам выражений сумма должна помочь вам понять всю вещь:

\s*: 0 или более пробелов
([<>]=?)?: A < или > знак после чего следует =, все дополнительные
!?: И дополнительно !
\d{1,5}: 1-5 цифр
(&|$): Либо & или конец строки

1

Начиная с вашего регулярного выражения, вы можете сделать это упрощение шаги:

(^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
  1. Перемещение якоря вне очереди

    ^(<=|<= |>= |>= |<|>|< |> |)((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    

    Почему существует были пробелы перед якорем? (Удалено что)

  2. Переместить следующий пробел снаружи и сделать его по желанию

    ^(<=|<=|>=|>=|<|>|<|>|) ?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  3. Удалить дубликаты в чередовании

    ^(<=|>=|<|>|) ?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  4. Пустой альтернатива в конце будет соответствовать пустой string ==> это чередование необязательно

    ^((<=|>=|<|>)? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  5. Сделайте знак равенства необязательными и удалить дубликаты

    ^((<|>)=? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  6. Чередование с одиночными символами могут быть заменены с классом персонажа

    ^([<>]=? ?)?((!|)([0-9]{1,5}))(& > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))* 
    
  7. делать подобные вещи с чередованием в конце, и вы в конечном итоге с чем-то вроде этого:

    ^([<>]=? ?)?((!|)([0-9]{1,5}))(?(& ?([<>]=?)?)?|$) 
    

Это непроверено, я не изменил семантический (я так думаю), но я сделал это только здесь, в редакторе.

Смежные вопросы