简介
对于刚使用 Linux 不久的同学,肯定会遇到这个问题,就是用 grep 匹配数字时,发现 \d 匹配不了数字。
主要原因是 grep 支持三种正则表达式 BRE、ERE、PCRE,而其默认使用的是 BRE,但 \d 是定义在 PCRE 中的,所以 grep 默认是不支持 \d 的。
正则表达式分类
BRE
基本的正则表达式(Basic Regular Expression 简称 BRE),由 posix 标准定义,为了统一历史上混乱的正则实现。ERE
扩展的正则表达式(Extended Regular Expression 简称 ERE),由 posix 标准定义,解决了一些BRE的缺陷并补充了一些新功能。PCRE
Perl 兼容的正则表达式(Perl Compatible Regular Expression 简称 PCRE),由 perl 语言发展而来,而后移植到各平台与编程语言中,所以称其为 Perl 兼容的正则表达式。
如今主流编程语言 (java, python) 中的正则实现,基本都是 PCRE,PCRE 功能也比 BRE, ERE 要强大得多,虽然大部分同学只知道其基础部分。
BRE, ERE, PCRE 对比
| 功能 | 描述 | BRE | ERE | PCRE |
|---|---|---|---|---|
| 字符组 | 匹配指定任一字符 | [..] |
[..] |
[..] |
| 排除字符组 | 匹配非指定任一字符 | [^..] |
[^..] |
[^..] |
| 简写字符组.号 | 匹配非换行字符 | . |
. |
. |
| 简写字符组 | 匹配数字 匹配非数字 |
不支持 | 不支持 | \d \D |
| 简写字符组 | 匹配字母数据下划线 匹配非字母数字下划线 |
\w \W |
\w \W |
\w \W |
| 简写字符组 | 匹配空白符 匹配非空白符 |
\s \S |
\s \S |
\s \S |
| 匹配量词 | 匹配0次或多次 | * |
* |
* |
| 匹配量词 | 匹配1次或多次 | \+ |
+ |
+ |
| 匹配量词 | 匹配0次或1次 | \? |
? |
? |
| 匹配量词 | 匹配x次 匹配x次或以上 匹配x次或以上y次或以下 |
\{x\} \{x,\} \{x,y\} |
{x} {x,} {x,y} |
{x} {x,} {x,y} |
| 懒惰匹配量词 | 尽量不匹配 | 不支持 | 不支持 | *? +? ?? {x}? {x,}? {x,y}? |
| 占有匹配量词 | 匹配后就不会回溯 | 不支持 | 不支持 | *+ ++ ?+ {x}+ {x,}+ {x,y}+ |
| 位置限定 | 匹配行开头位置 | ^ |
^ |
^ |
| 位置限定 | 匹配行结尾位置 | $ |
$ |
$ |
| 位置限定 | 匹配单词边界 匹配非单词边界 |
\b \B |
\b \B |
\b \B |
| 多选结构 | 多选匹配条件 | | |
` | ` |
| 捕获组与反向引用 | 分组并捕获 | \(...\) \1 \2 |
(...) \1 \2 |
(...) \1 \2 |
| 仅分组 | 仅分组不捕获括号 | 不支持 | 不支持 | (?:) |
| 固化分组 | 匹配后就不回溯的分组 | 不支持 | 不支持 | (?>) |
| 环视 | 零长度断言 | 不支持 | 不支持 | (?=...) (?!...) (?<=...) (?<!...) |
可以发现 BRE 与 ERE 的主要区别是,BRE 对于 +、?、{x}、|、(), 需要使用 \ 转义后,才能表达正则的含义,否则视为普通字符。而ERE默认表示正则元字符,加 \ 才是普通字符。
另外,对于我们常用的 \d,BRE 与 ERE 都不支持。
命令与它们的正则分类
grep
对于 grep,默认使用 BRE,grep -E或egrep使用 ERE,实际上grep -E与egrep是等价的,grep -P使用 PCRE。
另外,值得一提的是grep -F代表原始字符串匹配,grep -w代表单词模式匹配,如grep -w abc等价于grep '\babc\b',其中\b用于匹配单词边界。sed
对于 sed,默认也使用 BRE,sed -E或sed -r使用 ERE,sed 不支持 PCRE。awk
对于 awk 来说,默认就是 ERE,它不支持 BRE 与 PCRE。
扫描二维码,分享此文章