- 一、正则表达式引擎
- 二、正则表达式分类
- 三、正则表达式比较
- 四、Linux/OS X 下常用命令与正则表达式的关系
正则引擎大体上可分为不同的两类:DFA 和 NFA,而 NFA 又基本上可以分为传统型 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 匹配,也就是在找到最左侧最长匹配之前,它将继续回溯。同 DFA 一样,非贪婪模式或者说忽略优先量词对于 POSIX NFA 同样是没有意义的。
目前 JavaScript,Java,Php,Python,C# 等语言均实现了 NFA 引擎。
大多数语言和工具使用的是传统型的 NFA 引擎,它有一些 DFA 不支持的特性:
-
捕获组、反向引用和
$number引用方式; -
环视(Lookaround),
(?(?=…)、(?!…),或者有的有文章叫做预搜索; -
忽略优先量词
??、*?、+?、{m,n}?、{m,}?,或者有的文章叫做非贪婪模式; -
占有优先量词
?+、*+、++、{m,n}+、{m,}+,目前仅Java和PCRE支持,固化分组(?>…)。
按以上的说法,awk、egrep、lex 使用 DFA 引擎,所以不支持捕获组、反向引用和 $number 引用方式;不支持环视;不支持忽略优先修饰符;不支持占有优先修饰符。我觉得有问题,改天再验证吧!!
二、正则表达式分类在 Linux 和 OS X 下,常见的正则表达式,至少有以下三种:
- 基本的正则表达式(Basic Regular Expression 又叫 Basic RegEx 简称 BREs)
- 扩展的正则表达式(Extended Regular Expression 又叫 Extended RegEx 简称 EREs)
- Perl 的正则表达式(Perl Regular Expression 又叫 Perl RegEx 简称 PREs)
^匹配行首或者字符串的开始处^^^^$匹配行尾或者字符串的结尾处$$$$^$匹配空行^$^$^$^$\匹配单词结尾处,这种元字符的含义有问题>>不支持不支持,但是可以使用 \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\|yx|yx|yx|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
注意:
- js 中支持的是 EREs。
- 当使用 BREs ( 基本正则表达式 ) 时,必须在下列这些符号
?,+,|,{,},(,)前加上转义字符。
我曾经尝试在 grep 和 sed 命令中书写正则表达式,经常发现某些元字符不能直接使用,有些需要转义,有些又不需要转义,下面就梳理了不同的命令所支持的正则表达式种类。
命令正则表达式特定grep