登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

刁琳童 廊坊师范学院信息技术提高班十四期

做到最好。

 
 
 
 
 

日志

 
 

正则表达式(四)  

2017-03-08 15:31:58|  分类: 技术总结 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

位置指定

接下来的四个用于查找在某些内容之前后者之后的东西,就像\b^$这样,它也被称为零宽断言。用例子来说明:

(?=exe)也叫零宽先行断言,它匹配文本中的某些位置,这些位置的后面能匹配给定的后缀exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如果在查找I'm singing while you're dancing.时,它会匹配sing和danc。

(?<=exp)也叫零宽先行断言,它匹配文本中的某些位置,这些位置的签名能给定的前缀exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

如果你想要给一个很长的数字中每三位间加一个逗号(从右边加起),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})*\b

(?<=\s)\d+(?=\s)匹配以空白符间隔的数字,这个例子同时使用了前缀和后缀

 

负向位置指定

如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找一个单词,它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是这个表达式是有问题的,[^u]匹配一个字符,如果q出现在句子的结尾比如benq,这样句尾的逗号就会被匹配到,然后就会出现错误,[^u]可以匹配任意字符(空格,逗号,句号等)。负向位指定就可以解决这样的问题,因为它只匹配一个位置,并不消费任何字符。所以我们匹配可以用这样的正则表达式:\b\w*q(?!u)\w*\b

零宽负向先行断言(?!exp),只会匹配后缀exp不存在的位置。同理,我们可以用(?<!exp),零宽负向后行断言来查找前缀exp不存在的位置

一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。(<?(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b></b>之间的内容(不包括前缀和后缀本身)

 

注释

小括号的另一种用途是能过语法(?#comment)来包含注释。要包含注释的话,最好是启用忽略模式里的空白符选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。例如,我们可以把上一个表达式写成这样:

(?<=    # 查找前缀,但不包含它

<(\w+)> # 查找尖括号括起来的字母或数字(标签)

)       # 前缀结束

.*      # 匹配任意文本

(?=     # 查找后缀,但不包含它

<\/\1>  # 查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签

)       # 后缀结束

 

贪婪与懒惰

当正则表达式中包含很多重复的量词,通常是匹配尽可能多的字符。考虑如下的表达式:a.*b,它将会匹配最长以a开始,以b结束的字符串。如果用它来搜索aabab的话,那么它会搜索到整个字符串而不是ab或者aab。这便被称为贪婪匹配。

那么很容易理解,懒惰匹配就是尽可能少的匹配。只需要在贪婪模式的后面加上一个?就可以。这样.*?就意味着匹配任意数量的最少的重复。如果用它来匹配aabab的话,它匹配aabab

懒惰量词

*?

复任意次,但尽可能少重复

+?

1次或更多次,但尽可能少重复

??

0次或1次,但尽可能少重复

{n,m}?

nm次,但尽可能少重复

{n,}?

n次以上,但尽可能少重复

一些没有介绍到的表达式

\a

报警字符(打印它的效果是电脑嘀一声)

\b

通常是单词分界位置,但如果在字符类里使用代表退格

\t

制表符,Tab

\r

回车

\v

竖向制表符

\f

换页符

\n

换行符

\e

Escape

\0nn

ASCII代码中八进制代码为nn的字符

\xnn

ASCII代码中十六进制代码为nn的字符

\unnnn

Unicode代码中十六进制代码为nnnn的字符

\cN

ASCII控制字符。比如\cC代表Ctrl+C

\A

字符串开头(类似^,但不受处理多行选项的影响)

\Z

字符串结尾或行尾(不受处理多行选项的影响)

\z

字符串结尾(类似$,但不受处理多行选项的影响)

\G

当前搜索的开头

\p{name}

Unicode中命名为name的字符类,例如\p{IsGreek}

(?>exp)

贪婪子表达式

(?<x>-<y>exp)

平衡组

(?-<y>exp)

平衡组

(?im-nsx:exp)

在子表达式exp中改变处理选项

(?im-nsx)

为表达式后面的部分改变处理选项

(?(exp)yes|no)

exp当作零宽正向先行断言,如果在这个位置能匹配,使用yes作为此组的表达式;否则使用no

(?(exp)yes)

同上,只是使用空表达式作为no

(?(name)yes|no)

如果命名为name的组捕获到了内容,使用yes作为表达式;否使用no

(?(name)yes)

同上,只是使用空表达式作为no

 

  评论这张
 
阅读(144)| 评论(14)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018