正则表达式学习笔记

前言

很久以前就开始使用正则表达式,一直浅尝则止,知其然不知其所以然,前几天,在重构同事代码中的正则表达式时,遇到拦路虎,花了一个星期的业余时间,终于将正则表达式使用完全掌握,是为记

 

目录

一. 正则表达式是一个DSL

二. 正则表达式引擎

三. 语言元素

四. 参考

 

一. 正则表达式,事实上就是一个编程语言 (文本匹配DSL)

学习正则表达式,一定要把正则表达式作为一种编程语言,一种领域特点语言,在正则表达式引擎解释下执行,具有常规语言的流程结构,如下:

顺序:默认

分支:[]  |

循环:+ ? * {m,n}

封装:(子表达式)

 

二. 正则表达式引擎

DFA:从字符串中一个个取元素比较正则表达式

NFA:从正则表达式中取元素检查字符串

     采用贪婪算法(尽量多匹配),性能可能稍差但支持更多功能如下:

捕获组、反向引用和$number引用方式;

   环视(Lookaround,(?<=…)、(?<!…)、(?=…)、(?!…)),或者有的有文章叫做预搜索;

   忽略优化量词(??、*?、+?、{m,n}?、{m,}?),或者有的文章叫做非贪婪模式;

   占有优先量词(?+、*+、++、{m,n}+、{m,}+,目前仅Java和PCRE支持),固化分组(?>…)。

 

三. 语言元素

1. 占有字符和零宽度

占有字符:匹配并且将前移匹配点,如:

 [0-9a-zA-Z]

\n

.\w\d

 

零宽度:匹配但不前移匹配点,如:

^$\b            

(?=…)、正向肯定零宽断言

(?!…)、正向否定

(?<=…)、反向肯定

(?<!…)、反向否定

例如:

(?<=<(\w+)>).*(?=<\/ \1>)

匹配不包含属性的简单HTML标签内里的内容(注意\/是反斜线+斜线)

 

2. 子表达式

捕获并保存结果,用于后续使用

(exp) 子表达式, 同时进行捕获,如果不匹配使用前述零宽断言,如果不捕获使用(?:Exp)

\n前向引用子表达式, 如果捕获使用(\n),

(?<name>Exp)  命名子表达式

(?<name>)    前向引用明名子表达式

 

性能优化:(?>exp)  非回溯 或 贪婪匹配,如贪婪匹配不成功不尝试其他分支。

 

3. 或

(exp1|exp2|exp3) 

 

4. 匹配次数限定符

*: 匹配零次或多次   

+: 一次或多次

?:零次或一次

{n}: 精确匹配n次

{m,n}: 匹配次数在m到n之间

{n,}:匹配次数大于n

惰性匹配:在后面加?, 优先匹配次数少的, 如*?, +?, ??, {n,m}?, {n,}?

 

5. 优先级

正则表达式的计算方式与算术表达式非常类似;即从左到右进行计算,并遵循优先级顺序。

下表按从高到低的顺序包含了正则表达式运算符的优先级顺序。

运算符

说明

\

转义符

(), (?:), (?=), []

括号和中括号

*、+、?、{n}、{n,}、{n,m}

限定符

^、$、\任何元字符

定位点和序列

|

替换

字符具有高于替换运算符的优先级,例如,允许“m|food”匹配“m”或“food”。

 

 

四. 参考

http://blog.csdn.net/lxcnn 雁过无痕的博客

msdn正则表达式

 

 

posted @ 2013-10-24 23:18  iyxqj  阅读(224)  评论(0编辑  收藏  举报