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

Java 如何简化这个正则表达式?,java,regex,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*$ 从图形上看,它变成: 怎样才能减少呢 我尝试过正面的lookaheads,但没有成功((?=\d{4})[\s\d]+) 要求 正则表达式: 允许一到五对数字 允许数字对之间有零个或多个空白字符 以下是正则表达式必

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

^\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*$
从图形上看,它变成:

怎样才能减少呢

我尝试过正面的lookaheads,但没有成功(
(?=\d{4})[\s\d]+

要求 正则表达式:

  • 允许一到五对数字
  • 允许数字对之间有零个或多个空白字符
以下是正则表达式必须匹配的一组有效输入:

例子 编辑
解决方案:

直译:

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

即:

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

你可以看到一个演示。

这是我能制作的最好的

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

^\s*(\d{2} *){1,5}\s*$   <--- forgot the whitespaces 0 to n times (edit)
^(\d{2}?{1,5}$
^\s*(\d{2}*){1,5}\s*$让我们将其分解:

  • ^\s*(?:x)\s*$
    非常简单:输入的开始、任何空格、组x、任何空格、结束-这里不太简单
  • 现在x组:
    \d{2}\d{2}\s*\d{2}\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\s*\d{2}\d{2}\s*\br>>
    如果在管道处拆分(即“或”-运算符),则会得到以下结果:
    
    • \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*$
你可以试试这个

^\s*((?:\d{2}\s*){1,5})$
根据注释解释(正则表达式细分)


最短/最简单的是:

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

  • \d\d
    (4个字符)比
    \d{2}
    (5个字符,带量词)短/简单
  • 空格字符(1个字符)比
    \s
    (2个字符)更简单
  • 您不需要尾随的
    \s*
    ,因为任何尾随空格都会被内部表达式占用
请参阅通过所有发布的测试用例

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

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

还有另一种方法:

(\d\s*\d\s*){1,5}
正确匹配OP的所有示例:

匹配12
匹配1234
匹配123456
匹配12345678
匹配1234567890
匹配12 34
匹配123456
匹配12 34 56 78
匹配1234567890
没有匹配项123
没有匹配的12345
没有匹配的123 45

不匹配1 2 3 4 5在您的情况下,需要重复模式。你可以试试:

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

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

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


谢谢大家

这里的规则是什么?规则来匹配这些数字。你想匹配什么样的模式。我可以看到这些示例输入,但它们并没有说明要匹配的规则。正则表达式很长,很难理解。所以解释规则会更好。@noob“规则”对你来说是什么?对
^\s*\d{2}(\s*\d{2}){0,4}\s*$
有效吗?@noob:你误解了OP的评论。@noob enrico是正确的。在没有得到OP的澄清之前,你不应该将你的观点注入问题中。你的编辑改变了问题,足以使答案无效。将来,在自己编辑问题之前,通过评论询问OP以澄清要求,并且只有在您认为问题需要编辑时才进行编辑。将该
\s?
更改为
\s*
,您将匹配与原始表达式相同的内容。此外,“一个或多个空格”将是
\s+
而不是
\s?
。我认为
\s?
OP想要什么?如果OP在注释中指定,它应该能够允许超过12位数字。这不匹配
12345623453456
,它有5对,超过12位。@noob:我不明白。这不在OP的要求中。@enrico.bacis:阅读评论。OP应该提到这个问题。这就是我在第一条评论中谈到规则的原因。零个或多个空格。一开始我犯了一个错误,对不起。数字后面有零个或多个空格。这里有一个非常简单的解决方案。在我看来,使用非捕获括号更简单。@stephan我考虑过使用非捕获组,这对于正则表达式引擎来说更简单,但对于程序员来说更复杂。我将“更简单”解释为“程序员更简单”。这是一个很好的观点。为什么在开头使用括号?我已经添加了一个解释。我想那是在你的电脑里,而不是在你的电脑里comment@rock321987不,不会的。@Stephan我在那个链接中注意到regex的“味道”被设置为PHP,可能与Java的行为稍有不同。@AdamRice regex101还不支持Java。通常,PCRE(php)的行为与Java正则表达式风格非常接近。此处的输出来自Java应用程序,因此在本例中可能更准确。
^(\s*\d{2}(?:[^\S\n]*\d{2}){0,4}\s*)$
^(?:\s*\d{2}){1,5}$