我该如何简化这个正则表达式?

时间:2016-04-01 15:44:07

标签: java regex

这是一个相当复杂的正则表达式:

^\s*(?:\d{2}|\d{2}\s*\d{2}|\d{2}\s*\d{2}\s*\d{2}|\d{2}\s*\d{2}\s*\d{2}\s*\d{2}|\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2})\s*$

从图形上看,它变为:

Regular expression visualization

如何减少?

我尝试过积极的前瞻但没有成功(例如(?=\d{4})[\s\d]+)。

要求

正则表达式:

  • 允许一到五对数字。
  • 允许数字对之间包含零个或多个空白字符。

以下是正则表达式必须匹配的一组有效输入:https://regex101.com/r/hN0pT4/7

实施例

// OK                  // NOK
12                     123
1234                   12 345
123456                 123 45 45
12345678               1 2 3 4 5
1234567890             12 34 56 78 90 11
12 34
12 3456
12 34 56 78
12 34 567890

修改 解决方案:https://stackoverflow.com/a/36361240/363573

8 个答案:

答案 0 :(得分:7)

字面翻译如何:

  

之间有零个或多个空格的数字对(最多5对)

即:

^\s*(\d{2}\s*){1,5}\s*$

您可以看到演示here

答案 1 :(得分:3)

最短/最简单的是:

^ *(\d\d *){1,5}$

注意:

  • \d\d(4个字符)比\d{2}更短/更简单(5个字符,带量词)
  • space char(1 char)比\s(2个字符)
  • 更简单
  • 您不需要尾随\s*,因为内部表达式消耗了任何尾随空格

请参阅live demo传递所有已发布的测试用例。

如果您确实需要允许其他空白字符(例如制表符),请使用:

^\s*(\d\d\s*){1,5}$

答案 2 :(得分:2)

这是我能做的最好的

^(\d{2} ?){1,5}$

^\s*(\d{2} *){1,5}\s*$   <--- forgot the whitespaces 0 to n times (edit)

Expl:

^:字符串的开头

(\d{2} ?):匹配带有可选

的数字对

{1,5}:该组可以重复一到五次(最多5对)

$:字符串结尾

Regex101

答案 3 :(得分:2)

让我们分解一下:

  • ^\s*(?:x)\s*$很容易:输入的开头,任何空格,组x,任何空格,结束 - 只是简单地在这里。
  • 现在组x:\d{2}|\d{2}\s*\d{2}|\d{2}\s*\d{2}\s*\d{2}|\d{2}\s*\d{2}\s*\d{2}\s*\d{2}|\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}

    如果你在管道(即“或” - 操作员)拆分它,你得到这个:
    • \d{2}
    • \d{2}\s*\d{2}
    • \d{2}\s*\d{2}\s*\d{2}
    • \d{2}\s*\d{2}\s*\d{2}\s*\d{2}
    • \d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}

看模式?它们都以\d{2}开头,每次还有一个\s*\d{2} - 最多4次。所以这可以简化为\d{2}(?:\s*\d{2}){0,4}

将它组合在一起,即可获得^\s*(?:\d{2}(?:\s*\d{2}){0,4})\s*$

答案 4 :(得分:2)

你可以试试这个

^\s*((?:\d{2}\s*){1,5})$

根据评论解释( Regex Breakdown

^ #Starting of string
 \s* #Consume any spaces from starting
 (    #Capturing group to capture the whole string if it matches the below requirements (It is not necessary to use it if you are only matching the string)
   (?:\d{2}\s*){1,5} #Non capturing group to check the pattern
 )
$ #End of string

<强> Regex Demo

答案 5 :(得分:0)

这是另一种方式:

(\d\s*\d\s*){1,5}

正确匹配所有OP的例子:

匹配12
匹配1234
符合123456
符合12345678
符合1234567890
比赛12 34
比赛12 3456
比赛12 34 56 78
比赛12 34 567890
不匹配123
不匹配12 345
不匹配123 45 45
不匹配1 2 3 4 5

答案 6 :(得分:0)

在您的情况下,需要重复图案。你可以尝试:

^(\s*\d{2}(?:[^\S\n]*\d{2}){0,4}\s*)$

REGEX 101 DEMO

答案 7 :(得分:0)

这是我选择的最终解决方案:

^(?:\s*\d{2}){1,5}$

Regular expression visualization

谢谢大家!