Regular Expression

正则表达式

Text

模式 pattern

描述、匹配一系列匹配某个句法规则的字符串

定义

渊源

 - 模式匹配(SNOBOL语言)
 - 1956年 数学家Stephen Cole Kleene 用数学符号定义正则集(regular sets)
 - 1968年 两种用途:
 -  - Ken Thompson 用于编辑器 QED的文本匹配
 -  - 加入Unix编辑器ed 诞生grep:

g/ re /p--“Global search for Regular Expression and Print matching lines”
 -  - Douglas T. Ross等 **编译器设计中的词法分析**
 - 1970s,各种变体:Emacs 和 Unix的vi , lex , sed , AWK,expr
 - 1992年,形成标准POSIX.2

渊源

 - 1986年,Henry Spencer编写正则表达式库,后来为Tcl编写了一个高级正则表达式的实现
 - Perl使用并扩展了Spencer的原始库,不断增改功能和改bug
 - 1997年,Philip Hazel开始开发了PCRE (Perl Compatible Regular Expressions),模仿Perl的正则表达式功能,并被更多工具(PHP和Apache HTTP Server)使用

语法-分隔符

"re"    作为字符串输入(C,Java和Python)
/re/    /的用法起源于ed,是搜索编辑器的命令, 可以和其他命令组合,如g/re/p
s/re/replacement/    给出搜索和替换

s,re,replacement    避免escape的写法

语法-元字符

​字符缩略表示法 \n、\t...
八进制转义 \num
十六进制  \x
Unicode转义 \u
普通字符组 [a-z]、[^a-z] 
几乎任何字符 .
单个字节 \C
Unicode组合 \X
简记字符组 \w、\d、\s、\W、\D、\S
​起点 ^
终点  $
单词分界 \b、\B
顺序环视  ?=...、?!...
逆序环视 ?<=...、?<!...
分组/捕获  ()
多选 ...|...|...
量词  *、+、?、{num,num}

字符

字符组

锚点

组合

规则1

优先选择最左端的匹配结果

The dragging belly indicates that your cat is too fat.

/cat/

/fat|cat|belly|your/

规则2

标准量词是匹配优先的

?、*、+、{min,max}

匹配E-mail的header

/^Subject: (.*)/

/^Subject: (.*).*/

about 24 characters long

/^.*([0-9][0-9])/

Copyright 2003.

/^.*([0-9]+)/

应用

要求:匹配双引号内的内容

The name "McDonals's" is said "makudonarudo" in Japanese

/".*"/             

/"[^"]*"/

/“[^"\n]*”/              [^"]可以匹配换行符,点号不能

优化

-正确性:匹配期望的,不期望的匹配失败
-易于调整和理解
-效率

优化

-避免重新编译
-使用非捕获型括号
-不滥用括号
-不滥用字符组
-使用起始锚点

循环中声明
(?:xxx)                不适用于js
(.)* -> .*             捕获有代价
[a] ->a               字符组有代价
.*xxx->^.*xxx   减少回溯

优化

-从量词中提取文本      x+ -> xx*  -[3,5] -> ----{0,2}
-从多选结构提取文本  (this|that) -> th(is|at)
-从多选结构提取锚点  ^123|^abc -> ^(?:123|abc)

 

-减少多选
-最可能匹配的多选放最前  
-回溯最少的多选放最前        .*|a  -> a|.*  

应用

匹配ip地址

应用

/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/
/\d*\.\d*\.\d*\.\d*/

正确的量词->
/\d+\.\d+\.\d+\.\d+/
/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
/d/d?/d?   /d(/d/d?)?

应用

[0|1|2|3|...|254|255]
[0|00|000|1|01|001|...]

->/ \d | \d\d | \d\d\d /
->/ \d | \d\d | [01]\d\d | 2\d\d /
->/ \d | \d\d | [01]\d\d | 2[0-4]\d | 25[0-5]\d/
->/ [01]?\d?\d | 2[0-4]\d | 25[0-5]\d /
\d\d? vs \d?\d

/[01]?\d\d?|2[0-4]\d|25[0-5]\d/

更多

NFA引擎 vs DFA引擎 vs 混合(表达式优先/文本优先)


忽略优先(*?、+?、??、 {m,n}?

占有优先量词(*+、++、?+、 {m,n}+)

固化分组((?>......)

 

《精通正则表达式》--Jeffrey Friedl

Thank You

Regular Expression

By bellst

Regular Expression

  • 90