c正则表达式语法大全 POSIX语法量词分组速查
时间:2026-08-10 | 作者:骑光打字机 | 阅读:0C语言标准库本身不提供正则表达式语法,常见实现主要依赖POSIX regex接口。本篇系统整理BRE与ERE、字符类、量词、分组、反向引用、转义规则、编译与执行标志及regmatch_t用法,便于查询和编写可移植代码。
C语言中的正则表达式
C语言标准并未内置正则表达式引擎。在Linux、macOS等系统中,通常使用regex.h提供的POSIX接口;其他环境可能采用PCRE2等第三方库。POSIX正则表达式分为基本正则表达式(BRE)和扩展正则表达式(ERE)。regcomp默认按BRE编译,传入REG_EXTENDED后改用ERE。
- BRE:分组写作(...),区间量词写作{m,n};标准BRE没有选择符、加号量词和问号量词
- ERE:分组、选择及量词直接写作(...)、|、+、和{m,n}
- 反向引用1至9是BRE规定的能力;ERE中的反斜杠加数字不具备POSIX可移植性
- POSIX接口头文件:
regex.h - 编译函数:regcomp
- 匹配函数:regexec
- 释放函数:regfree
基础字符与匹配规则
普通字母和数字通常匹配自身。未启用REG_NEWLINE时,点号可以匹配包括换行符在内的任意单个字符;启用REG_NEWLINE后,点号不匹配换行符。反斜杠用于改变部分字符的含义,但具体规则还取决于使用BRE还是ERE。
abc:匹配连续文本abc- .:默认匹配包括换行符在内的任意单个字符
- .:匹配字面量半角点号;对应的C字符串应写成"."
- [
abc]:匹配a、b、c中的任意一个字符 - [^
abc]:匹配除a、b、c之外的单个字符;启用REG_NEWLINE后不匹配换行符 - [a-z]:匹配由当前区域设置解释的小写字母范围
- [0-9]:匹配单个数字字符
量词语法
量词限定前一个字符、字符类或分组的重复次数。ERE支持星号、加号、问号和花括号范围;BRE可直接使用星号,区间量词需要写成{m,n}。标准BRE不提供加号和问号量词,部分实现支持的+和属于扩展,不能作为可移植语法依赖。POSIX也不提供懒惰量词。
- ERE a*:匹配零个或多个a
- ERE a+:匹配一个或多个a
- ERE a:匹配零个或一个a
ERE a{3}:匹配连续三个aERE a{2,}:匹配至少两个aERE a{2,5}:匹配二至五个a- BRE a{2,5}:基本语法中的区间量词
- ERE [0-9]+:匹配一串数字
分组、选择、反向引用与锚点
ERE用圆括号分组并用竖线表示选择;BRE分组写作(...),且没有标准选择运算符。脱字符和美元符分别限制行或字符串的开头与结尾。BRE可用1至9引用此前匹配的子表达式,ERE反向引用不属于POSIX标准。regexec可通过regmatch_t数组返回整个匹配及各子表达式的位置。
- ERE (
abc):将abc作为一个子表达式 - BRE (
abc):将abc作为一个子表达式 - ERE cat|dog:匹配cat或dog
- ERE ^(cat|dog)$:只匹配完整的cat或dog
- ^
abc:要求abc位于开头;REG_NEWLINE还允许^匹配换行符后的行首 abc$:要求abc位于结尾;REG_NEWLINE还允许$匹配换行符前的行尾- BRE ^(ab)1$:匹配abab,使用第一个子表达式的反向引用
- ^$:匹配空字符串;启用REG_NEWLINE时也可匹配空行位置
方括号表达式与POSIX字符类
方括号表达式用于匹配一个字符。脱字符只有紧跟左方括号时才表示否定;连字符通常表示范围,放在开头或结尾可表示字面量;右方括号要作为普通字符时通常放在列表开头。方括号内不能依赖反斜杠转义获得可移植结果,应通过字符位置或POSIX结构表达。字符范围和类别可能受当前区域设置影响。
- [
abc]:匹配a、b、c中的一个 - [^
abc]:匹配不在列表中的一个字符 - []a]:匹配右方括号或a
- [-
abc]或[abc-]:匹配字面量连字符或列表中的字符 - [a-z]:范围端点及排序受区域设置影响
- [+]:可移植地匹配ERE元字符加号
- [.]:匹配字面量点号
- [[:digit:]]:匹配数字字符
- [[:alpha:]]:匹配字母字符
- [[:alnum:]]:匹配字母或数字字符
- [[:space:]]:匹配空白字符
- [[:lower:]]:匹配小写字母
- [[:upper:]]:匹配大写字母
- [[:xdigit:]]:匹配十六进制数字
- [[:punct:]]:匹配标点字符
- [.ch.]和[=
a=]:分别表示排序元素和等价类,实际行为依赖区域设置及实现
C字符串中的转义
正则表达式先由C编译器解析为字符串,再由正则引擎解析。因此,需要传递一个反斜杠给正则引擎时,C源码中通常要写成两个反斜杠。匹配ERE元字符的字面量时,方括号表达式往往更清晰且更具可移植性。
- C字符串"^[0-9]+$":以ERE匹配完全由数字组成的非空字符串
- C字符串"^[[:space:]]*$":匹配空串或仅含空白的字符串
- C字符串".":向正则引擎传递.,匹配字面量半角点号
- C字符串"a[+]b":以可移植ERE写法匹配文本a+b
- [+]、[]和[|]等方括号表达式适合匹配ERE元字符本身
- 正则中的反斜杠通常要在C字符串中再次转义
编译标志与REG_NEWLINE
regcomp的cflags决定语法和编译行为。REG_EXTENDED选择ERE,REG_ICASE忽略字母大小写,REG_NOSUB表示调用者不需要匹配位置,REG_NEWLINE改变换行符、点号、锚点及否定方括号表达式的处理。多个标志可按位或组合。
- REG_EXTENDED:使用ERE;未指定时使用BRE
- REG_ICASE:匹配时忽略字母大小写,具体字符规则受区域设置影响
- REG_NOSUB:只关心是否匹配;regexec的nmatch和pmatch参数会被忽略
- REG_NEWLINE:点号不匹配换行符
- REG_NEWLINE:否定方括号表达式不匹配换行符,即使列表没有明确排除换行符
- REG_NEWLINE:^除字符串开头外还匹配换行符后的行首
- REG_NEWLINE:$除字符串结尾外还匹配换行符前的行尾
执行标志与regmatch_t
regexec的eflags用于描述本次执行的边界条件。REG_NOTBOL和REG_NOTEOL不会删改输入,只会让字符串起点或终点不被视为可供^或$匹配的边界。启用REG_NEWLINE后,^和$对输入内部换行符形成的行边界仍然有效。未启用REG_NOSUB时,可用regmatch_t数组接收匹配区间。
- REG_NOTBOL:字符串起点不作为^可匹配的开头
- REG_NOTEOL:字符串终点不作为$可匹配的结尾
- REG_NOTBOL与REG_NOTEOL可按位或组合传给regexec
- pmatch[0]:整个表达式的匹配区间
- pmatch[1]起:各子表达式的匹配区间,数量受nmatch限制
- rm_so:匹配起点相对输入字符串起始地址的字节偏移
- rm_eo:匹配末尾后一位置的字节偏移
- 未参与匹配的可选子表达式通常以rm_so和rm_eo均为-1表示,读取区间前应先检查
- 使用REG_NOSUB编译后,应以nmatch为0、pmatch为NULL调用regexec
regcomp与regexec用法
先声明regex_t对象并调用regcomp编译表达式,再用regexec执行匹配。regcomp返回零表示编译成功;regexec返回零表示匹配成功,返回REG_NOMATCH表示没有匹配,其他错误可用regerror转换为可读信息。只应对成功编译的regex_t对象调用regfree。
regcomp(®ex, pattern, REG_EXTENDED):按ERE编译表达式regcomp(®ex, pattern, REG_EXTENDED | REG_ICASE):按ERE编译并忽略字母大小写regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB):编译仅用于判断结果的表达式regcomp(®ex, pattern, REG_EXTENDED | REG_NEWLINE):启用逐行相关规则regexec(®ex, text, 0, NULL, 0):只判断是否存在匹配regexec(®ex, text, count, matches, REG_NOTBOL):执行匹配并将输入起点视为非行首regerror(code, ®ex, buffer, size):获取错误说明regfree(®ex):释放已成功编译的正则资源
常用ERE表达式示例
以下示例按REG_EXTENDED语法书写。表达式应根据输入边界和业务规则调整。仅检查字符串中是否存在片段时可以省略首尾锚点;验证完整输入时通常需要同时使用开头和结尾锚点。复杂格式还应在正则匹配后进行范围或业务逻辑校验。
- ^[0-9]+$:匹配非空整数数字串
- ^[+-][0-9]+$:匹配带可选正负号的整数
- ^[[:alpha:]_][[:alnum:]_]*$:匹配常见标识符形式
- ^[^@[:space:]]+@[^@[:space:]]+.[^@[:space:]]+$:进行基础邮箱格式检查
- ^([0-9]{1,3}.){3}[0-9]{1,3}$:进行IPv4外形检查,仍需验证每段范围
- ^[[:space:]]*(.*[^[:space:]])[[:space:]]*$:匹配可带首尾空白的内容;启用REG_NEWLINE时点号不跨越换行符
常见问题与兼容性
不同正则引擎的语法并不完全相同。POSIX ERE没有标准环视、非捕获分组、懒惰量词及d、w、s等PCRE简写。部分系统会提供超出POSIX的扩展,但编写跨平台程序时不应依赖未被标准保证的转义或行为,并应明确语法类型、编译标志、执行标志和区域设置。
- 不要把PCRE语法直接当作POSIX语法使用
- 不要把实现提供的BRE +、或ERE反向引用当作可移植语法
- 不要在方括号表达式中依赖反斜杠转义连字符或右方括号
- 不要忘记C字符串自身的转义层
- 不要用regexec返回值直接当作布尔真值解释
- 不要在regcomp失败后对未成功编译的对象调用regfree
- 使用regmatch_t中的可选分组前应检查rm_so和rm_eo是否为-1
- 需要完整验证时不要遗漏首尾锚点
- 格式匹配通过后仍应检查数值范围和业务约束
掌握BRE与ERE差异、方括号表达式、REG_NEWLINE等标志、C字符串转义及regex.h接口后,即可更可靠地处理文本查找与格式验证。对于环视、Unicode属性、复杂替换或其他POSIX未规定的能力,应选择功能更完整的正则库,并以该库及目标系统的官方文档为准。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- c++11 正则表达式 std::regex写法与异常处理
- 时间:2026-08-10
-
- vc 正则表达式 std::regex与Boost.Regex选择
- 时间:2026-08-10
-
- c++ 正则表达 regex匹配提取替换示例
- 时间:2026-08-10
-
- 正则表达式c语言
- 时间:2026-08-10
-
- c正则表达式 regex.h语法函数与完整代码
- 时间:2026-08-10
-
- c 正则表达式 regex.h匹配提取示例
- 时间:2026-08-10
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15