四种正则层级
grep 有四种模式层级,选错层级是最常见的隐性坑。默认是基本正则 BRE,其中 + ? | ( ) 都是普通字符,要有特殊含义必须加反斜杠;-E 启用扩展正则 ERE,这些元字符直接生效;-P 启用 PCRE,支持 \d、\s 与前后瞻断言;-F 按固定字符串匹配,不解释任何正则符号,速度最快。症状很典型:命令不报错,但匹配结果为空,因为 + 与 | 在 BRE 下被当成了字面量。
基本信息
| 适用平台 | Linux 的 GNU grep 支持 -P;BSD 与 macOS 自带 grep 默认不支持 -P |
|---|---|
| 命令语法 | grep [-E|-F|-P] 模式 [文件] |
| 模式层级 | 默认 BRE;-E 扩展正则 ERE;-P PCRE;-F 固定字符串 |
| 常用元字符 | ^ 行首 $ 行尾 . 任意字符 * 重复 [ ] 字符集 {n,m} 次数 \b 词边界 |
| 配套选项 | -i 忽略大小写 -v 反向选择 -w 全词 -r 递归 --include 按文件名过滤 |
典型使用场景
- 多条件筛选:用 error|warn|fail 一次匹配多种关键字
- 格式校验:匹配日期、IP、UUID 等固定格式的字符串
- 字段提取:用 -oP 的后向断言取出键值对中的值
- 字面量搜索:代码或配置里含 . ( ) 等符号时用 -F 避免误解释
- 排除注释:用 ^[^#] 过滤掉配置文件里的注释行
常用示例
常用示例
grep -E 'error|warn|fail' app.log # ERE 多条件
grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}' app.log # 匹配日期前缀
grep -oP '(?<=user=)[^ ]+' app.log # 后向断言提取值
grep -F 'a.b(c)' file # 字面量搜索,不解释正则
grep -E '^[^#]' /etc/nginx/nginx.conf # 排除注释行
grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log | head # IPv4 粗匹配模式层级对照
| 层级 | 启用选项 | 行为差异 |
|---|---|---|
| BRE | 默认 | + ? | ( ) 需加反斜杠才有特殊含义 |
| ERE | -E | 元字符直接生效,日常多条件匹配首选 |
| PCRE | -P | 支持 \d \s 与前后瞻,仅 GNU grep 且编译时启用才有 |
| 固定串 | -F | 不解释任何元字符,速度最快,搜符号串最稳 |
搜索含特殊符号的字面量时优先 -F:不解释正则、速度最快,也不会因为少转义一个括号而得到空结果。
-P 并非所有平台都编译支持,BSD 与 macOS 自带的 grep 就没这个选项。需要跨平台运行的脚本应使用 -E 与 POSIX 字符类,避免依赖 PCRE。
方言差异对照
| 写法 | 默认模式下的含义 | 说明 |
|---|---|---|
| + 与 ? | 普通字符 | 要当量词使需 -E 或反斜杠转义 |
| | 与 () | 普通字符 | 分组与择一同样需要 -E |
| \b 词边界 | GNU 扩展 | POSIX 未定义,换实现可能失效 |
| {n,m} 范围量词 | 需转义写法 | 不同实现的支持程度不一致 |
| -o 输出片段 | 通用选项 | 抽取字段比整行匹配更合适 |
写模式前先想清楚「要的是字面量还是语法」:同一串字符在基本正则下是普通字符、在扩展正则下是运算符,多数「匹配不上」的困惑都来自这层差异。跨平台脚本里只用 -E 能表达的子集,比依赖单个实现的高阶特性更容易维护。