正規表示式和 CPU 100 有什麼故事?

2021-08-21 05:22:59 字數 2294 閱讀 7467

public

static

void

main

(string args)

[pp]://|[hh][tt][pp][ss]://)(([a-za-z0-9-~]+).)+([a-za-z0-9-~\\\\/])+$";

string bugurl = "";

if (bugurl.matches(badregex))  else 

}

^([hh][tt][pp]://|[hh][tt][pp][ss]://)(([a-za-z0-9-~]+).)+([a-za-z0-9-~\\/])+$

而一旦發生回溯,那其消耗的時間就會變得很長,有可能是幾分鐘,也有可能是幾個小時,時間長短取決於回溯的次數和複雜度。

正規表示式引擎

(deterministic final automata 確定型有窮自動機)和 nfa 自動機

(non deterministic finite automaton 不確定型有窮自動機)。

text="today is a nice day."

regex="day"

讀取到正規表示式的第二個匹配符:a。那著繼續和字串的第四個字元 a 比較,又匹配了。那麼接著讀取正規表示式的第三個字元:y。

讀取到正規表示式的第三個匹配符:y。那著繼續和字串的第五個字元 y 比較,又匹配了。嘗試讀取正規表示式的下乙個字元,發現沒有了,那麼匹配結束。

nfa自動機的回溯

text="abbc"

regex="abc"

讀取正規表示式第二個匹配符 b 和字串的第二個字元 b 比較,匹配了。但因為 b 表示 1-3 個 b 字串,以及 nfa 自動機的貪婪特性(也就是說要盡可能多地匹配),所以此時並不會再去讀取下乙個正規表示式的匹配符,而是依舊使用 b 和字串的第三個字元 b 比較,發現還是匹配。於是繼續使用 b 和字串的第四個字元 c 比較,發現不匹配了。此時就會發生回溯。

發生回溯是怎麼操作呢?發生回溯後,我們已經讀取的字串第四個字元 c 將被吐出去,指標回到第三個字串的位置。之後,程式讀取正規表示式的下乙個操作符 c,讀取當前指標的下乙個字元 c 進行對比,發現匹配。於是讀取下乙個操作符,但這裡已經結束了。

^([hh][tt][pp]://|[hh][tt][pp][ss]://)(([a-za-z0-9-~]+).)+([a-za-z0-9-~\\/])+$

第二部分:校驗網域名稱。(([a-za-z0-9-~]+).)+。

第三部分:校驗引數。([a-za-z0-9-~\\/])+$。

匹配到 ******.

匹配到 com/dzfp-web/pdf/download?request=6e7jgm38jf.....,你會發現因為貪婪匹配的原因,所以程式會一直讀後面的字串進行匹配,最後發現沒有點號,於是就乙個個字元回溯回去了。

解決方案

public

static

void

main

(string args)

[pp]://|[hh][tt][pp][ss]://)(([a-za-z0-9-~]+).)+([a-za-z0-9-~_%\\\\/])+$"

;string bugurl = "";if

(bugurl.matches(badregex)) else

}

、懶惰模式

、獨佔模式

。。但是懶惰模式還是會發生回溯現象的。todo

例如下面這個例子:

text="abbc"

regex="ab?c"

^([hh][tt][pp]://|[hh][tt][pp][ss]://)

(([a-za-z0-

9-~]+).)++    --->>> (這裡加了個+號)

([a-za-z0-

9-~\\/])+$

^([hh][tt][pp]:\/\/|[hh][tt][pp][ss]:\/\/)(([a-za-z0-9

-~]+).)++([a-za-z0-9

-~\\\/])+$

樹義有話說

正規表示式概述 什麼是正規表示式

正規表示式概述 正規表示式在程式語言中存在著廣泛的應用,特別是用來處理字串。如匹配字串 查詢字串 替換字串等。可以說,正規表示式是一段文字或乙個公式,它是用來描述用某種模式去匹配一類字串的公式,並且該公式具有一定的模式。本小節將介紹正規表示式的基本概念 第乙個正規表示式,以及測試正規表示式的工具co...

正規表示式裡面 和 有什麼區別?

s匹配任意的空白符 包括空格,製表符 tab 換行符,中文全形空格 s則是任意不是空白符的字元 涉及到貪婪模式 當正規表示式中包含能接受重複的限定符時,通常的行為是 在使整個表示式能得到匹配的前提下 匹配盡可能多的字元。以這個表示式為例 a.b,它將會匹配最長的以a開始,以b結束的字串。如果用它來搜...

正規表示式 正規表示式 總結

非負整數 d 正整數 0 9 1 9 0 9 非正整數 d 0 負整數 0 9 1 9 0 9 整數 d 非負浮點數 d d 正浮點數 0 9 0 9 1 9 0 9 0 9 1 9 0 9 0 9 0 9 1 9 0 9 非正浮點數 d d 0 0 負浮點數 正浮點數正則式 英文本串 a za z...