哈嘍,我是老吳。我的日常工作基本離不開正則表達(dá)式,不過一般是在 Shell 腳本或者命令行里使用。今天抽空了解了一下 C 語言下的使用方式,馬上分享給大家。如果你還不了解正則表達(dá)式,可以先瞅一眼 《Linux Shell 腳本攻略》第 4.2 章節(jié)正則表達(dá)式入門。
五分鐘就可以入門,下面來看第一個(gè)例子。
#include?<regex.h> static?const?char?*const?str?= ???????"1)?John?Driverhacker;n2)?John?Doe;n3)?John?Foo;n"; static?const?char?*const?re?=?"John.*o"; int?main(void) { ???static?const?char?*s?=?str; ???regex_t?????regex; ???regmatch_t??pmatch[1]; ???regoff_t????off,?len; ???if?(regcomp(®ex,?re,?REG_NEWLINE)) ???????exit(EXIT_FAILURE); ???printf("Matches:n"); ???for?(int?i?=?0;?;?i++)?{ ???????if?(regexec(®ex,?s,?ARRAY_SIZE(pmatch),?pmatch,?0)) ???????????break; ???????off?=?pmatch[0].rm_so?+?(s?-?str); ???????len?=?pmatch[0].rm_eo?-?pmatch[0].rm_so; ???????printf("#%d:n",?i); ???????printf("offset?=?%jd;?length?=?%jdn",?(intmax_t)?off, ???????????????(intmax_t)?len); ???????printf("substring?=?"%.*s"n",?len,?s?+?pmatch[0].rm_so); ???????s?+=?pmatch[0].rm_eo; ???} }
運(yùn)行結(jié)果:
$?./example? Matches: #0: offset?=?25;?length?=?7 substring?=?"John?Do" #1: offset?=?38;?length?=?8 substring?=?"John?Foo"
成功匹配出符合 "John.*o" 表達(dá)式的兩個(gè)字符串。
一般正則表達(dá)式相關(guān)的接口就是 2 個(gè):1、編譯,對(duì)應(yīng) regcomp();2、查找匹配項(xiàng),對(duì)應(yīng) regexec();匹配到的結(jié)果會(huì)保存在結(jié)構(gòu)體 regmatch_t 里,注意,這個(gè)結(jié)構(gòu)體里只保存了匹配項(xiàng)的 start offset 和 end offset。
typedef?struct?{ ????regoff_t?rm_so; ????regoff_t?rm_eo; }?regmatch_t;
如果你的系統(tǒng)不是 Linux,而是嵌入式 RTOS 或者裸機(jī)程序,可以使用這個(gè)開源的正則表達(dá)式庫:
https://github.com/kokke/tiny-regex-c
tiny-regex-c 是一個(gè)有 1K star 的超小巧 C 語言 regex 庫。源碼就 2 個(gè)文件:re.c 和 re.h,超容易移植。用法看這個(gè)例子:
#include?"re.h" int?main(void) { ????/*?Standard?int?to?hold?length?of?match?*/ ????int?match_length; ????/*?Standard?null-terminated?C-string?to?search:?*/ ????const?char*?string_to_search?=?"ahem..?'hello?world?!'?.."; ????/*?Compile?a?simple?regular?expression?using?character?classes,?meta-char?and?greedy?+?non-greedy?quantifiers:?*/ ????re_t?pattern?=?re_compile("[Hh]ello?[Ww]orlds*[!]?"); ????/*?Check?if?the?regex?matches?the?text:?*/ ????int?match_idx?=?re_matchp(pattern,?string_to_search,?&match_length); ????if?(match_idx?!=?-1)?{ ????????printf("match:?%sn",?string_to_search?+?match_idx); ????} }
運(yùn)行結(jié)果:
match:?hello?world?!'?..
tiny-regex-c 的 接口和 第一個(gè)例子 的posix regex 類似,都是一目了然,就不再贅述了。
—— The End ——