1. 程式人生 > 其它 >這grep咋還不支援\d呢(BRE,ERE,PCRE)

這grep咋還不支援\d呢(BRE,ERE,PCRE)

原創:打碼日記(微信公眾號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對比

功能 描述 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 -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文字命令技巧(下)
字元編碼解惑