正则表达式的分类
文章目錄
- 一、正則表達式引擎
- 二、正則表達式分類
- 三、正則表達式比較
- 四、Linux/OS X 下常用命令與正則表達式的關系
一、正則表達式引擎
正則引擎大體上可分為不同的兩類:DFA 和 NFA,而 NFA 又基本上可以分為傳統(tǒng)型 NFA 和 POSIX NFA。
DFA(Deterministic Finite Automaton) 確定型有窮自動機
NFA(Non-deterministic finite automaton) 非確定型有窮自動機
(1) Traditional NFA
(2) POSIX NFA
DFA 引擎因為不需要回溯,所以匹配快速,但不支持捕獲組,所以也就不支持反向引用和 $number 這種引用方式,目前使用 DFA 引擎的語言和工具主要有 awk、egrep 和 lex。
POSIX NFA 主要指符合 POSIX 標準的 NFA 引擎,它的特點主要是提供 longest-leftmost 匹配,也就是在找到最左側最長匹配之前,它將繼續(xù)回溯。同 DFA 一樣,非貪婪模式或者說忽略優(yōu)先量詞對于 POSIX NFA 同樣是沒有意義的。
目前 JavaScript,Java,Php,Python,C# 等語言均實現了 NFA 引擎。
大多數語言和工具使用的是傳統(tǒng)型的 NFA 引擎,它有一些 DFA 不支持的特性:
捕獲組、反向引用和 $number 引用方式;
環(huán)視(Lookaround),(?<=…)、(?<!…)、(?=…)、(?!…),或者有的有文章叫做預搜索;
忽略優(yōu)先量詞??、*?、+?、{m,n}?、{m,}?,或者有的文章叫做非貪婪模式;
占有優(yōu)先量詞?+、*+、++、{m,n}+、{m,}+,目前僅 Java 和 PCRE 支持,固化分組 (?>…)。
按以上的說法,awk、egrep、lex 使用 DFA 引擎,所以不支持捕獲組、反向引用和 $number 引用方式;不支持環(huán)視;不支持忽略優(yōu)先修飾符;不支持占有優(yōu)先修飾符。我覺得有問題,改天再驗證吧!!
二、正則表達式分類
在 Linux 和 OS X 下,常見的正則表達式,至少有以下三種:
三、正則表達式比較
| ^ | 匹配行首或者字符串的開始處 | ^ | ^ | ^ | ^ |
| $ | 匹配行尾或者字符串的結尾處 | $ | $ | $ | $ |
| ^$ | 匹配空行 | ^$ | ^$ | ^$ | ^$ |
| \< | 匹配單詞開始處。例如,\<liao,表示匹配以 liao 開頭的單詞。等價于 \bliao | \< | \< | 不支持 | 不支持,但是可以使用 \b 來匹配單詞邊界 |
| \> | 匹配單詞結尾處 | \> | \> | 不支持 | 不支持,但是可以使用 \b 來匹配單詞邊界 |
| > | 匹配單詞結尾處,這種元字符的含義有問題 | > | > | 不支持 | 不支持,但是可以使用 \b 來匹配單詞邊界 |
| ? | 匹配前面的子表達式 0 次或者 1 次;匹配前面的子表達式 0 個或 1 個;匹配 0 個或 1 個前面的子表達式;匹配 0 個或 1個前面的子表達式所代指的字符串;匹配 0 個或 1 個前面的子表達式所匹配到的字符串 | 不支持,需要轉義 | ? | ? | ? |
| \? | 匹配前面的子表達式 0 次或者 1 次,這種元字符的含義有問題 | \? | 不支持 | 不支持 | 不支持 |
| ? | 問號跟在任何一個量詞后面,則變成非貪婪匹配模式。 | 不支持 | 不支持 | 不支持 | 不支持 |
| . | 匹配除了換行符以外的任意一個字符(awk 指令中的句點 . 可以匹配換行符 \n) | . | .(如果要匹配包含換行符在內的任意單個字符,可以使用 [\s\S]) | . | .(如果要匹配包含 \n 在內的任意一個字符,可以使用 [.\n]) |
| * | 匹配前面的子表達式任意次;匹配前面的子表達式任意個;匹配任意次前面的子表達式 | * | * | * | * |
| + | 匹配前面的子表達式 1 次或者多次 | 需要轉義 | + | + | + |
| {n} | n 是一個非負整數,表示匹配前面的子表達式 n 次 | 需要轉義,\{n\} | {n} | {n} | {n} |
| x|y | 匹配 x 或者 y | 需要轉義,x\|y | x|y | x|y | x|y |
| \d | 匹配從 0 到 9 中的任意一個數字字符 | 不支持 | 不支持 | \d | \d |
| \D | 匹配非數字的任意一個字符 | 不支持 | 不支持 | \D | \D |
| \S | 匹配除了空白字符以外的任意一個字符 | 不支持 | 不支持 | \S | \S |
| \s | 匹配任意一個空白字符,等價于 [\f\n\r\t\v] | 不支持 | 不支持 | \s | \s |
| \W | 匹配除了英文字母、數字、下劃線以外的任意一個字符 | \W | \W | \W | \W |
| \w | 匹配英文字母、數字、下劃線中的任意一個字符 | \w | \w | \w | \w |
| \B | 匹配非單詞邊界,例如,er\B 可以匹配 here 中的 er,但是不能匹配 hier 中的 er | \B | \B | \B | \B |
| \b | 匹配單詞邊界 | \b | \b | \b | \b |
| \f | 匹配一個換頁符。等價于 \x0c 和 \cL | 不支持 | 不支持 | \f | \f |
| \n | 匹配一個換行符。等價于 \x0a 和 \cJ | 不支持 | 不支持 | \n | \n |
| \r | 匹配一個回車符。等價于 \x0d 和 \cM | 不支持 | 不支持 | \r | \r |
| \t | 匹配一個橫向制表符。等價于 \x09 和 \cI | 不支持 | 不支持 | \t | \t |
| \v | 匹配一個垂直制表符。等價于 \x0b 和 \cK | 不支持 | 不支持 | \v | \v |
| \cx | 匹配由 x 指明的控制字符。例如,\cM 匹配一個 Control-M 或回車符,x 的值必須為一個英文字母,否則 c 被視為一個普通字符 | 不支持 | 不支持 | \cx | |
| \xn | 匹配 n,其中 n 為十六進制轉義值。十六進制轉義值必須為確定的兩個數字長。例如,\x41 匹配 A 。正則表達式中可以使用 ASCII 編碼。 | 不支持 | 不支持 | 支持 | |
| \num | 其中 num 為一個正整數,表示對所獲取的匹配的引用 | 不支持 | \num | \num |
注意:
四、Linux/OS X 下常用命令與正則表達式的關系
我曾經嘗試在 grep 和 sed 命令中書寫正則表達式,經常發(fā)現某些元字符不能直接使用,有些需要轉義,有些又不需要轉義,下面就梳理了不同的命令所支持的正則表達式種類。
| grep | 支持 BREs、EREs、PREs 正則表達式。 1. 指令后不跟任何參數, 則表示要使用 “BREs”; 2. grep 指令后跟 ”-E” 參數, 則表示要使用 “EREs”; 3. grep 指令后跟 “-P” 參數, 則表示要使用 “PREs”。 |
| egrep | 支持 EREs、PREs 正則表達式。 1. egrep 指令后不跟任何參數, 則表示要使用 “EREs”; 2. egrep 指令后跟 “-P” 參數, 則表示要使用 “PREs”。 |
| sed | 支持 BREs、EREs。 1. sed 指令默認是使用 “BREs”; 2. sed 指令后跟 “-r” 參數 , 則表示要使用“EREs”。 |
| awk | 支持 EREs,并且默認使用 “EREs”。 |
總結
- 上一篇: HTML行内元素/行级元素/内联元素/行
- 下一篇: 正则表达式的捕获性分组/反向引用