正規表示式
核心共振
⚡超越一切震懾凡人⚡
⚡帶來終結機械降神⚡
⚡風暴之力充滿全身⚡
⚡最後一擊核心共振⚡
就是首先你需要知道一些元字元,也就是它的語法。
最基本的幾個:
^
$
分別指定行首和行尾。
[abc]
表示匹配 a,b,c 中的一個,當然長度不限。也有一些符合人類直覺的寫法:[a-o]
表示從 a 到 o 的所有小寫字母,[1-9]
[A-X]
也都是對的。
[^abc]
表示匹配除了 a,b,c 中的一個,將 ^
放到 []
裡相當於取反。
{a}
{a,}
{a,b}
分別表示匹配恰好 \(a\) 次,至少 \(a\) 次,\([a,b]\) 次。
.
表示一個任意除回車(\n
和 \r
)字元,在某些時候(如 C 中不指定 REG_NEWLINE
時)也會匹配回車。
()
用於劃分單元,將其中的內容作為一個單元匹配,可以用 \x
來引用第 \(x\) 段以獲取的匹配,如 (.)\1
匹配兩個相同字元,在 C++ 中查詢時會先儲存整個的匹配,再將每段分別儲存。
|
就是或,兩邊有一邊成立就匹配。
\b
匹配單詞和空格的邊界,並不匹配字元。
\B
\b
取反。
\f \n \r \t \v
就是字面意思,匹配換頁,換行,製表等。
\<
\>
分別匹配詞首和詞尾,分隔符不一定是空格。
會了上面的基本就會所有了,下面的大多都是上面的的等價簡略寫法。
?
等價 {0,1}
+
等價 {1,}
\d
等價 [0-9]
\s
匹配不可見,等價 [\f\n\r\t\v]
\w
匹配包括下劃線在內的所有單詞字元,等價 [0-9A-Za-z_]
\D
\S
\W
上面那仨的取反。
然後想在 C++ 裡用正規表示式,還要學一點語法。
考慮一下速度,boost 的功能強大但有非常“優秀”的速度,C++ 的速度在匹配不上時較快,匹配上時飛慢,而且查詢也是飛慢,所以這裡建議大家用 C 裡的 regex.h
,雖然好像只有 linux
能用。
用法就是首先你要引用 <regex.h>
庫。
一共兩個型別,四個函式:
regex_t
:用來存已經編譯好的正規表示式。
int regcomp(regex_t &a,const char *s,int t)
:a
就是用來存的,s
是需要編譯的表示式,t
是編譯 tag,一共四個,等號後面是它的值:REG_EXTENDED=1
使用更牛的庫,一般是要加的,REG_ICASE=2
設定大小寫不敏感,REG_NEWLINE
如果不加,預設忽略回車,就會導致 ^
$
只能匹配第一個和最後一個,且 .
能匹配回車,加上了就完全取反,REG_NOSUB
不返回匹配結果,只返回是否成功匹配。
regmatch_t
:用來存匹配結果,.rm_so
表示起點,.rm_eo
是終點加一。
int regexec(regex_t &a,const char *s,size_t x,regmatch_t &c,int t)
:表示用表示式 a
匹配(或者說查詢) s
;x
是儲存個數,會將正串匹配和 \(x-1\) 前個單元的匹配放到 c
,若制定了 REG_NOSUB
會忽略;t
是 tag,一共兩種,REG_NOTBOL=1
表示禁用 ^
,REG_NOTEOL=2
表示禁用 $
,若指定了 REG_NEWLINE
會忽略,返回值為 \(0\) 表示找到了,為其他表示沒找到或出現錯誤;每次只能匹配第一個,要匹配所有的話寫迴圈每次位移即可。
因為 regcomp
分配了記憶體,所以在每次編譯後都要用 void regfree(regex_t &a)
來釋放記憶體。理論上每次重新編譯也要先釋放,但是實測不釋放也能過,不知道會不會有其他問題。
regerror
是在產生錯誤後返回錯誤資訊,感覺沒啥用,可以自行百度。
有個板子:正規表示式