6

I am looking for a way to simplify a regular expression which consists of values (e.g. 12345), relation signs (<,>,<=,>=) and junctors (&,!). E.g. the expression:

>= 12345 & <=99999 & !55555 

should be matched. I have this regular expression:

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

I am especially unhappy with the repetition of <=, >=, <, > at the beginning and end of the expression. I would be glad to get a hint how to make it simpler e.g. look ahead, look back.

4

6 回答 6

1

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

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

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

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

  2. 将以下空格移到外部并使其可选

    ^(<=|<=|>=|>=|<|>|<|>|) ?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  3. 删除交替中的重复项

    ^(<=|>=|<|>|) ?((!|)([0-9]{1,5}))( & > | & < |& >=|&>=|&<=||&<=|&>=|&<|&>|&| &| & |$))*
    
  4. 最后的空替代将匹配空字符串 ==> 此替代是可选的

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

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

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

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

这是未经测试的,我没有改变语义(我认为是这样),但我只是在编辑器中这样做了。

于 2012-05-23T21:25:03.823 回答
0

怎么样

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

这会照顾你的 > / >= / < / <= 重复。似乎对我有用。

让我知道这是否回答了您的问题或需要工作。

于 2012-05-23T20:33:46.710 回答
0

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

像这样,我认为

(^[<>]=?\s?)((!|)([0-9]{1,5}))(\s?&\s?[<>]=?\s|$)*
于 2012-05-23T20:33:32.547 回答
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");

但是我们仍然在猜测您是在谈论验证还是其他内容。

于 2012-05-23T20:39:14.767 回答
0

您似乎花费了很多精力来匹配可选空间。像\s?(0 - 1) 或\s*(0 - many) 这样的东西会更好。

此外,被某物分隔的重复项目总是很困难。最好为“事物”制作一个正则表达式以简化重复。

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- 可能是您最终实现 & 分隔列表的方式;如果您可以在语言中使用字符串连接,则不需要解析器) .

于 2012-05-23T20:50:18.413 回答
0

这就是你想要的:

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

这些 sum 子表达式的解释应该可以帮助您理解整个事情:

\s*: 0 个或多个空格
([<>]=?)?: 一个<>符号可选地后跟一个=, 全部可选
!?: 和可选!
\d{1,5}: 1-5 位
(&|$): 一个&或字符串的结尾

于 2012-05-23T20:56:45.460 回答