用正規表示式捕獲識別符號 隨便說

2021-09-05 13:17:56 字數 1005 閱讀 5246

假設只接受public/private兩個修飾符,並且只接受void/bool/int三個返回型別,接受字段、屬性和函式。函式不允許有引數,屬性有get/set(為簡單起見,先get後set),字段只能是bool/int兩個型別(不允許初始化)。函式和屬性的內容為空,只有一對花括號。那是不是應該這麼寫呢?

(?(?public|private)\s+(?void|bool|int)\s+(?\w+)\s*\(\s*\))|(?(?public|private)\s+(?void|bool|int)\s+(?\w+)\s*\s*set\s*\s*})|(?(?public|private)\s+(?bool|int)\s+(?\w+)\s*;)

這麼寫是對的,但是效率方面卻不是很好。對於這個簡單的情況可能還是體現不出來,但是如果更加複雜的話,可能就會出現效率低下的問題了。我們應該怎麼怎麼改呢?

(?(?public|private)\s+(?>(?void)\s+(?\w+)\s*(?>(?\(\s*\)\s*)|(?\s*set\s*\s*}))|(?bool|int)\s+(?\w+)\s*(?>(?\(\s*\)\s*)|(?\s*set\s*\s*})|(?;))))

這種寫法跟上面那一種寫法有什麼不一樣呢?對於

public int aaaaaaaaaaaaaa;

這乙個句子,前面的正規表示式需要嘗試function這一組的匹配,在分號位置匹配失敗之後退到匹配的開始位置。然後再嘗試匹配property這一組,在同乙個位置匹配失敗,然後回溯到起點,最後才成功匹配variable這一組。換句話說,對於這句話來說,幾乎每乙個字元都被比較和匹配了三次。如果問題更複雜一點,這樣的寫法可能就會存在多個地方需要回溯匹配,效率就更低下了。而後面一種寫法,在每個地方都是確定的,如果不能夠匹配的話,整個匹配就必然失敗,而完全不需要回溯。

注意上面所有a|b的關係的地方都會用(?>a|b)的形式來指定,如果匹配成功了,就不會再回溯到原來的地方嘗試另外一種可能。在正規表示式裡面,總是會嘗試最大匹配,如果不使用(?>a|b)的形式的話。這是什麼意思呢?

留給大家思考吧。

正規表示式基本標識

表示匹配字串的開始位置 比如 用在中括號中 時,可以理解為取反,表示不匹配括號中字串 表示匹配字串的結束位置 表示匹配 零次到多次 表示匹配 一次到多次 至少有一次 表示匹配零次或一次 表示匹配單個字元 表示為或者,兩項中取一項 小括號表示匹配括號中全部字元 中括號表示匹配括號中乙個字元 範圍描述 ...

正規表示式 標識 i g m

regexp中宣告標誌 標誌作為regexp建構函式的第二個引數,其可以用如下方式宣告 var patt1 new regexp 規則 模式 標誌 正規表示式直接量中宣告標誌 與其他語法不同的是,在正規表示式直接量中宣告標誌,是在 符號之外說明的,即它們不出現在兩個斜槓之間,而是位於第二個斜槓之後。...

js 正規表示式捕獲型

測試demo 本文案例位址 分組有四種型別 見案例 捕獲型 非捕獲型 正向前瞻型 反向前瞻型 捕獲性分組 就是捕獲分組所匹配的內容暫且儲存在某個地方,以便下次使用,捕獲性分組以 表示,有些地方將取得捕獲性分組所匹配結果的過程稱之為 反向引用 測試demo中有針對這個的專門案例 非捕獲性分組不捕獲分組...