[英]Java Matcher slow regex
這是一個非常簡單的正則表達式,它在一個非常短的字符串上運行了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
第一部分(?=)是斷言字符串最多包含這些字符
第二部分是斷言,例如在這種情況下字符串不會超出語法,以防止使用-並至少在[a-z0-9]中結束
我試圖猜測你的意圖,但這並不容易:
(?=[a-z0-9-]{1,63})
這種前瞻性似乎要求下一個最多63個字符為小寫ASCII字母或數字,但實際上,即使有只有一個字母后跟任何東西。 因此,也許您的意思是(?=[a-z0-9-]{1,63}$)
禁止使用不超過63個字符的合法字符。
您似乎想要在-
之間添加至少一個字母或數字的組,但您使-
可選項的目的並不是真正地創建約束,而是允許產生很多可能性的方式,從而增加了表達式的開銷。 您可以簡單地說: ([a-z0-9]++-){0,63}[a-z0-9]+
。 花括號中的組至少需要一個字母或數字,之后需要減號,結尾處的表達式在表達式末尾至少需要一個字母或數字,但也將匹配最后一個沒有后綴的組-
同時。 如果沒有-
則最后一組可能也是唯一的一組-
完全包含在您的文本中。
將所有正則表達式放在一起將成為: (?=[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}
--
在字符串中,請使用否定的前瞻(?!.*--)
。 {1}
。 $
(?=[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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.