简化复杂的正则表达式

时间:2012-05-23 20:24:21

标签: java regex

我正在寻找一种简化正则表达式的方法,该正则表达式由值(例如12345),关系符号(<,>,< =,> =)和junctors(&,!)组成。例如。表达式:

>= 12345 & <=99999 & !55555 

应该匹配。我有这个正则表达式:

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

我特别不满意重复&lt; =,&gt; =,&lt;,&gt;在表达的开头和结尾。我很乐意得到一个提示如何使其更简单,例如展望未来,回头看看。

6 个答案:

答案 0 :(得分:1)

从正则表达式开始,您可以执行此简化步骤:

 (^<=|^<= | ^>= | ^>= |^<|^>|^< |^> |^)((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
  1. 将锚移出交替

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

    为什么锚之前有空格? (删除)

  2. 将以下空格移到外面并将其设为可选

    ^(<=|<=|>=|>=|<|>|<|>|) ?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  3. 删除替换

    中的重复项
    ^(<=|>=|<|>|) ?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  4. 最后的空替代字符将匹配空字符串==&gt;这种交替是可选的

    ^((<=|>=|<|>)? ?)?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  5. 使等号可选并删除重复项

    ^((<|>)=? ?)?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  6. 单个字符的替换可以替换为字符类

    ^([<>]=? ?)?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  7. 最后用交替进行类似的事情,你最终会得到类似的东西:

    ^([<>]=? ?)?((!|)([0-9]{1,5}))( ?(& ?([<>]=?)?)?|$)
    
  8. 这是未经测试的,我没有改变语义(我想是这样),但我只是在编辑器中这样做。

答案 1 :(得分:0)

您可以将所有空格设置为可选(带有问号),这样您就不必明确列出所有可能性。您还可以将字符集([])中的相等/不等号符号分组。

像这样,我想

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

答案 2 :(得分:0)

怎么样

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

照顾你的&gt; /&gt; = /&lt; /&lt; =重复。似乎对我有用。

如果这回答了您的问题,或者需要工作,请告诉我。

答案 3 :(得分:0)

我有一个两步程序。首先打破junctor,然后检查各个部分。

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");

但是我们仍在猜测你是在谈论验证还是别的什么。

答案 4 :(得分: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的结构 - 可能是你最终实现&amp; -separated列表的方式;如果你不需要解析器可以在语言中使用字符串连接。)

答案 5 :(得分:0)

这就是你想要的:

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

sum子表达式的这些解释应该有助于你理解整个事情:

\s*:0或更多空格
([<>]=?)?<>符号可选后跟=,所有选项为 !?:可选!
\d{1,5}:1-5位数 (&|$)&或字符串

的结尾