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