这是一个非常简单的正则表达式,它在一个非常短的字符串上运行超过30秒:(i7 3970k @ 3.4ghz
)
Pattern compile = Pattern.compile("^(?=[a-z0-9-]{1,63})([a-z0-9]+[-]{0,1}){1,63}[a-z0-9]{1}$");
Matcher matcher = compile.matcher("test-metareg-rw40lntknahvpseba32cßáàâåäæç.nl");
boolean matches = matcher.matches(); //Takes 30+ seconds
第一部分(?=)是断言字符串最多包含以下字符
第二部分是断言字符串不超过语法,例如在这种情况下,以防止--s,并至少在[a-z0-9]中结束
我试着猜测你的意图,但并不容易:
(?=[a-z0-9-]{1,63})
这种展望似乎打算要求接下来的63个字符是小写ASCII字母或数字,但事实上,即使只有一个字母后面跟着任何东西,它也会成功。所以,也许你的意思是(?=[a-z0-9-]{1,63}$)
禁止在最多63个合法字符之后的任何其他内容。
您似乎希望-
之间至少有一个字母或数字的组,但您将-
设置为可选,这并没有真正创建约束,并允许使用许多可能的方法,这会造成表达式的开销。你可以简单地说:([a-z0-9]++-){0,63}[a-z0-9]+
。大括号内的组至少需要一个字母或数字,并且需要减号。之后,末尾的表达式至少需要表达式末尾的一个字母和数字,但同时也将匹配最后一个没有以下-
的组。如果文本中根本不包含-
,那么最后一组可能也是唯一一组。
把所有这些放在一起,regex就变成了:(?=[a-z0-9-]{1,63}$)([a-z0-9]++-){0,63}[a-z0-9]+
。请注意,如果使用matches
方法,则不需要前导^
或尾随$
;它已经暗示了字符串边界必须与表达式边界匹配。
我希望我理解你的意思…
我修复了这个正则表达式,如下所示替换它:
^(?=[a-z0-9-]{1,63})([a-z0-9]{0,1}|[-]{0,1}){1,63}[a-z0-9]{1}$
部分([a-z0-9]+[-]{0,1}){1,63}
变为:([a-z0-9]{0,1}|[-]{0,1}){1,63}
- 如果您想确保字符串中没有
--
,只需使用负向前看(?!.*--)
- 写CCD_ 17也没有意义
- 另一件事是,如果您想确保字符串最多有63个字符,那么在您的展望中,您需要在
(?=[a-z0-9-]{1,63}$)
的末尾添加$
所以也许^(?=[a-z0-9-]{1,63}$)(?!.*--)[a-z0-9-]+[a-z0-9]$
我认为根据您的说法,您的正则表达式可以简化为编辑-(为了子孙后代)在阅读@Holger的帖子后,我正在更改这一点,以修复可能发生的灾难性回溯,并加快速度,正如我的长椅所示,这可能是最快的方法。
# ^(?=[a-z0-9-]{1,63}$)[a-z0-9]++(?:-[a-z0-9]+)*+$
^ # BOL
(?= [a-z0-9-]{1,63} $ ) # max 1 - 63 of these characters
[a-z0-9]++ (?: - [a-z0-9]+ )*+ # consume the characters in this order
$ # EOL