簡體   English   中英

Java Matcher慢速正則表達式

[英]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}
  • 另一件事是,如果要確保字符串最多包含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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM