查看原文
其他

这grep咋还不支持\d呢(BRE,ERE,PCRE)

扣钉日记 扣钉日记 2022-11-27

原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。

简介

对于刚使用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对比

功能描述BREEREPCRE
字符组匹配指定任一字符[..][..][..]
排除字符组匹配非指定任一字符[^..][^..][^..]
简写字符组.号匹配非换行字符...
简写字符组匹配数字
匹配非数字
不支持不支持\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 -Eegrep使用ERE,实际上grep -Eegrep是等价的,grep -P使用PCRE。

另外,值得一提的是grep -F代表普通字符串匹配,grep -w代表单词模式匹配,如grep -w abc等价于grep '\babc\b',其中\b用于匹配单词边界。

sed
对于sed,默认也使用BRE,sed -Esed -r使用ERE,sed不支持PCRE。

awk
对于awk来说,默认就是ERE,它不支持BRE与PCRE。

另外,PCRE发布了两个新的轮子pcregreppcre2grep,功能上类似于grep,不过是专门用PCRE规范实现的,pcre2grep有个好用的功能,可以很方便的使用正则提取数据,如下:

echo -e 'name:zhangsan,age:18 \n name:lisi,age:20' | pcre2grep -O '$1 $2' 'name:(\w+),age:(\d+)'
zhangsan 18
lisi 20

往期内容

不容易自己琢磨出来的正则表达式用法
原来awk真是神器啊
Linux文本命令技巧(上)
Linux文本命令技巧(下)
字符编码解惑


长按关注【打码日记】


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存