首页 > 代码库 > 正则表达式(2)

正则表达式(2)

一、正则表达式-单行与多行模式

补充:

.点
匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。

开启多行模式

^ 可以匹配字符串开头(字符串的开始位置),也可以匹配行的开头(即换行符\n之后的位置) $ 可以匹配字符串结尾(字符串的结束位置), 也可以匹配行的结尾(即换行符\n之前的位置)

关闭多行模式

^ 只能匹配字符串开头 $ 只能匹配字符串结尾

正则表达式:(?m)^\d\w+(\r)(\n)

例:abcde

结果:

ab
cd
e

在windows操作系统中其实是:ab[CR][LF]cd[CR][LF]e

CR用符号‘\r‘表示, ASCII代码是13, 十六进制为0x0D; 
LF用符号‘\n‘表示, ASCII代码是10, 十六进制为0x0A;

 

从网站上获取的HTML源码,极少有不换行的。这时候单行模式派上用场了,它可以改变点符号的意义。

一般认为点符号(.)是匹配任意单个字符的,而(.*)就是匹配任意多个字符。但实际上点符号不能匹配换行符。在Windows中与它等效的表达式为[^\r\n]。

1.单行模式的嵌入修饰符:
我们可以直接在正则表达式中嵌入单行模式:

(?s)<div>.*</div>

(?s)修饰符说明,其后面的表达式采用单行模式。所以使用时请不要将它放在末尾。另外可以使用(?-s)关闭单行模式。

2. 多行模式(Multiline)

MSDN定义:更改 ^ 和 $ 的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。

  定义 影响的表达式 RegexOptions枚举 嵌入标识符
单行模式 更改点 (.) 的含义,使它与每一个字符匹配(而不是与除 \n 之外的每个字符匹配)。 . Singleline (?s)
多行模式 更改 ^ 和 $ 的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。 ^$ Multiline (?m)
忽略大小写 指定不区分大小写的匹配。   IgnoreCase (?i)

 二.贪婪匹配

什么是贪婪匹配和非贪婪匹配

贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。

非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。

编程中如何区分两种模式: 默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。

 

表1.懒惰限定符
代码/语法 说明
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复  

举例: 

源字符串:aa<div>test1</div>bb<div>test2</div>cc 

正则表达式一:<div>.*</div> 

匹配结果一:<div>test1</div>bb<div>test2</div> 

正则表达式二:<div>.*?</div> 

匹配结果二:<div>test1</div>(这里指的是一次匹配结果,所以没包括<div>test2</div>) 
转载大神的例子

在上面从应用角度分析贪婪与非贪婪模式时,一直提到的一个前提条件就是“整个表达式匹配成功”,为什么要强调这个前提,我们看下下面的例子。 

正则表达式三:<div>.*</div>bb 

匹配结果三:<div>test1</div>bb 

修饰“.”的仍然是匹配优先量词“*”,所以这里还是贪婪模式,前面的“<div>.*</div>”仍然可以匹配到“<div>test1</div>bb<div>test2</div>”,但是由于后面的“bb”无法匹配成功,这时“<div>.*</div>”必须让出已匹配的“bb<div>test2</div>”,以使整个表达式匹配成功。这时整个表达式匹配的结果为“<div>test1</div>bb”,“<div>.*</div>”匹配的内容为“<div>test1</div>”。可以看到,在“整个表达式匹配成功”的前提下,贪婪模式才真正的影响着子表达式的匹配行为,如果整个表达式匹配失败,贪婪模式只会影响匹配过程,对匹配结果的影响无从谈起。 

正则表达式四:<div>.*?</div>cc 

匹配结果四:<div>test1</div>bb<div>test2</div>cc 

这里采用的是非贪婪模式,前面的“<div>.*?</div>”仍然是匹配到“<div>test1</div>”为止,此时后面的“cc”无法匹配成功,要求“<div>.*?</div>”必须继续向右尝试匹配,直到匹配内容为“<div>test1</div>bb<div>test2</div>”时,后面的“cc”才能匹配成功,整个表达式匹配成功,匹配的内容为“<div>test1</div>bb<div>test2</div>cc”,其中“<div>.*?</div>”匹配的内容为“<div>test1</div>bb<div>test2</div>”。可以看到,在“整个表达式匹配成功”的前提下,非贪婪模式才真正的影响着子表达式的匹配行为,如果整个表达式匹配失败,非贪婪模式无法影响子表达式的匹配行为。 

 

匹配原理:

http://www.jb51.net/article/31491.htm 

正则表达式(2)