C 正则表达式
nxdong August 03, 2022 [linux, c] #regexc 正则表达式的一些用法参考
代码
my_regex.c
内容如下:
void
int
编译运行
运行结果:
)
)
)
)
)
)
)
)
注意事项
regcomp
正则表达式的编译很费时间。在实际应用中不要每次都重新编译表达式。regfree
与regcomp
成对使用。避免内存泄露。err_msgbuf
的内容可能超过256 在表达式很长的时候。 实际使用应当根据实际情况设置更大值或者动态申请。可以通过size_t err_size = regerror(rc, &preg, NULL, 0);
动态获取错误信息的长度。并且申请资源后重新获取错误信息。nmatch
的值与pmatch
的大小要跟实际表达式的子表达式(括号内的表达式)的数量匹配。为子表达式的数量+1。 子表达式的数量可以通过编译后的regex_t
结构的re_nsub
字段获取。注意,动态申请的结构要释放。- 根据匹配结果的下标取匹配串的时候要保证原字符串的存在。
- 根据粗略的测试。
ERE
的编译效率比BRE
高。而且表达式更容易理解。 - BRE(Base Regular Expressions) 与 ERE(POSIX-Extended Regular Expressions) 的区别可以参考 文档
写正则表达式是个很繁琐的事情。可以利用一些工具进行调试。然后再翻译到对应语言的表达式。
便捷参考
内容来自 POSIX-Extended_Regular_Expressions
特殊字符 | 说明 |
---|---|
. | 匹配任何单字符 (许多应用不包含换行, 确切的说哪个字符被看作换行与风格, 字符编码,操作系统等因素相关的['\r','\n','\r\n']. 但是假定包含换行是安全的.). 在 POSIX 中括号表达式内, 点字符匹配字面意义上的点字符 . . 例如: a.c 匹配 "abc", 但是[a.c] 只匹配 "a", ".", 或者 "c". |
[ ] | 方括号表达式. 匹配一个在方括号内的字符. 例如: [abc] 匹配 "a", "b", 或者 "c". [a-z] 匹配一个 "a" 与 "z"之间的小写字母. 这些模式可以混合使用: [abcx-z] 匹配 "a", "b", "c", "x", "y", 或者 "z", 跟 [a-cx-z] 一样.- 在方括号表达式的开头(在^ 后面) 或结尾的时候看作字面量.例如: [abc-] , [-abc] . 注意.不允许反斜杠转义(这里应该指不允许转义[],其他的字符应该是允许的). ] 字符可以出现在方括号表达式的第一个(在 ^ 之后),例如: []abc] . |
[^ ] | 匹配一个不包含在方括号内的字符. 例如: [^abc] 匹配除了 "a", "b", 或者 "c"的任何单个字符. [^a-z] 匹配任何小写"a" 与 "z"之外的单个字符.跟上面一样,字符字面量与范围可以混用. |
^ | 匹配字符串的开头位置. 在基于行的工具中,他匹配任一行的开头位置. |
$ | 匹配字符串的结尾位置或者字符串结尾符之前的位置. 在基于行的工具中,他匹配任一行的结尾位置. |
BRE: \( \) ERE: ( ) | 定义一个被标记的子表达式. 被匹配的字符串可以被重新提起.(参考下一条 _n_ ). 被标记的表达式也可以叫做block(块)或者capturing group(捕获组). |
_n_ | 匹配 n 次被子表达式匹配的字符, n 是一个1到9 之间的数. 这个构造从理论上就不合理,而且没有被POSIX ERE 语法接受. 一些工具允许匹配超过9次. 不要用这个语法 |
* | 匹配0次或多次前面的元素. 例如: ab*c 匹配 "ac", "abc", "abbbc", 等. [xyz]* 匹配 "", "x", "y", "z", "zx", "zyx", "xyzzy"等. \(ab\)* (BRE) 或者 (ab)* (ERE) 匹配 "", "ab", "abab", "ababab"等. |
BRE: \+ ERE: + | 匹配1次或多次前面的元素. 例如: ab\+c (BRE) 或者 ab+c (ERE) 匹配 "abc", "abbbc", 等, 而不是 "ac". [xyz]\+ (BRE) 或者 [xyz]+ (ERE) 匹配 "x", "y", "z", "zx", "zyx", "xyzzy"等. \(ab\)\+ (BRE) 或者 (ab)+ (ERE) 匹配 "ab", "abab", "ababab"等. |
BRE: \? ERE: ? | 匹配0次或 1次前面的元素. 例如: ab\?c (BRE) 或者 ab?c (ERE) 匹配 "ac" 和 "abc", \(ab\)\? (BRE) 或者 (ab)? (ERE) 匹配 "" or "ab". |
BRE: \| ERE: | | 匹配前面或者后面的元素. 例如: abc|def (BRE) 或者 abc|def (ERE) 匹配 "abc" 和 "def". |
BRE: \{_m_,_n_\} ERE: {_m_,_n_} | 匹配前面的元素至少m次,不多于n次. 例如: a\{3,5\} (BRE) or a{3,5} (ERE) 只匹配 "aaa", "aaaa", 与 "aaaaa". |
BRE: \{_m_\} ERE: {_m_} | 恰好匹配前面的元素m次. |
BRE: \{_m_,\} ERE: {_m_,} | 匹配前面的元素至少m次. |
BRE: \{,_n_\} ERE: {,_n_} | 匹配前面的元素不多于n次. 例如: ba\{,2\}b (BRE) or ba{,2}b (ERE) 只匹配 "bb", "bab", 与 "baab". |
便捷表达
POSIX class | similar to | meaning |
---|---|---|
[:upper:] | [A-Z] | 大写字母 |
[:lower:] | [a-z] | 小写字母 |
[:alpha:] | [[:upper:][:lower:]] | 大写字母 和 小写字母 |
[:alnum:] | [[:alpha:][:digit:]] | 数字,大写字母 和 小写字母 |
[:digit:] | [0-9] | 数字 |
[:xdigit:] | [0-9A-Fa-f] | 16进制字母 |
[:punct:] | [.,!?:…] | 标点符号 |
[:blank:] | [ \t] | 空格和TAB |
[:space:] | [ \t\n\r\f\v] | 空白字符 |
[:cntrl:] | 控制字符 | |
[:graph:] | [^\t\n\r\f\v] | 可打印字符 |
[:print:] | [^ \t\n\r\f\v] | 可打印字符和空格 |
参考
在 *unix 系统中, 可以通过 man regcomp
等命令参考系统自带的文档。