2024.11.20 鲜花

正则表达式

核心共振

⚡超越一切震慑凡人⚡

⚡带来终结机械降神⚡

⚡风暴之力充满全身⚡

⚡最后一击核心共振⚡

就是首先你需要知道一些元字符,也就是它的语法。

最基本的几个:

^ $ 分别指定行首和行尾。

[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 匹配(或者说查找) sx 是存储个数,会将正串匹配和 \(x-1\) 前个单元的匹配放到 c,若制定了 REG_NOSUB 会忽略;t 是 tag,一共两种,REG_NOTBOL=1 表示禁用 ^REG_NOTEOL=2 表示禁用 $,若指定了 REG_NEWLINE 会忽略,返回值为 \(0\) 表示找到了,为其他表示没找到或出现错误;每次只能匹配第一个,要匹配所有的话写循环每次位移即可。

因为 regcomp 分配了内存,所以在每次编译后都要用 void regfree(regex_t &a) 来释放内存。理论上每次重新编译也要先释放,但是实测不释放也能过,不知道会不会有其他问题。

regerror 是在产生错误后返回错误信息,感觉没啥用,可以自行百度。

有个板子:正则表达式

P

posted @ 2024-11-20 14:27  xrlong  阅读(36)  评论(1编辑  收藏  举报