正则表达式

         在编写处理字符串的程序或⽹网页时,经常会有查找符合某些复杂规则的字符串的需要。 正则表达式 就是⽤用于描述这些规则的⼯工具。换句话说,正则表达式就是记录⽂文本规则的代码。 

         很可能你使⽤用过Windows/Dos下⽤用于⽂文件查找的 通配符(wildcard) ,也就是 * ? 。如果你想查找某个⽬目录下的所有的Word⽂文档的话,你会搜索 *.doc 。在这⾥里, * 会被解释成任意的字符串。和通配符类似,正则表达式也是⽤用来进⾏行⽂文本匹配的⼯工具,只不过⽐比起通配符,它能更精确地描述你的需求——当然,代价就是更复杂——⽐比如你可以编写⼀一个正则表达式,⽤用来查找 所有以0开头,后⾯面跟着2-3个数字,然后是⼀一个连字号“-”,最后是7或8位数字的字符串 (像 010-12345678 0376-7654321 )。

⽐比如 him , history , high 等等。⽤用 hi 来查找的话,这⾥里边的 hi 也会被找出来。如果要 精确地查找hi这个单词 的话,我们应该使⽤用 \bhi\b 。 

\b 是正则表达式规定的⼀一个特殊代码(好吧,某些⼈人叫它 元字符,metacharacter ),代表着 单词的开头或结尾,也就是单词的分界处 。虽然通常英⽂文的单词是由空格,标点符号或者换⾏行来分隔的,但是 \b 并不匹配这些单词分隔字符中的任何⼀一个,它只匹配⼀一个位置

. 是另⼀一个元字符,匹配 除了换⾏行符以外的任意字符 。 * 同样是元字符,不过它代表的不是字符,也不是位置,⽽而是数量——它指定* 前边的内容可以连续重复使⽤用任意次以使整个表达式得到匹配 。因此, .* 连在⼀一起就意味着 任意数量的不包含换⾏行的字符 。

0\d\d-\d\d\d\d\d\d\d\d 匹配这样的字符串: 以0开头,然后是两个数字,然后是⼀一个连字号“-”,最后是8个数字 (也就是中国的电话号码。当然,这个例⼦子只能匹配区号为3位的情形)。

这⾥里的 \d 是个新的元字符,匹配 ⼀一位数字(0,或1,或2,或…⋯…⋯) 。 - 不是元字符,只匹配它本⾝身——连字符(或者减号,或者中横线,或者随你怎么称呼它)。

为了避免那么多烦⼈人的重复,我们也可以这样写这个表达式: 0\d{2}-\d{8} 。这⾥里 \d 后⾯面的 {2}( {8} )的意思是前⾯面 \d 必须连续重复匹配2次(8次) 。 

  正则表达式⾥里还有更多的元字符,⽐比如 \s 匹配 任意的空⽩白符,包括空格,制表符(Tab),换⾏行符,中⽂文全⾓角空格等 。 \w 匹配 字母或数字或下划线或汉字等 。 

\ba\w*\b 匹配 以字母 a 开头的单词——先是某个单词开始处( \b ),然后是字母 a ,然后是任意数量的字母或数字( \w* ),最后是单词结束处( \b ) 。\d+ 匹配 1个或更多连续的数字 。这⾥里的 + 是和 *类似的元字符,不同的是 * 匹配 重复任意次(可能是0次) ,⽽而 + 则匹配 重复1次或更多次 。\b\w{6}\b 匹配刚好6个字符的单词。 

元字符 ^ (和数字6在同⼀一个键位上的符号)和 $ 都匹配⼀一个位置,这和 \b 有点类似。 ^ 匹配你要⽤用来查找的字符串的开头, $ 匹配结尾。这两个代码在验证输⼊入的内容时⾮非常有⽤用,⽐比如⼀一个⽹网站如果要求你填写的QQ号必须为5位到12位数字时,可以使

⽤用: ^\d{5,12}$

这⾥里的 {5,12} 和前⾯面介绍过的 {2} 是类似的,只不过 {2} 匹配 只能不多不少重复2次 , {5,12} 则是 重复的次数不能少于5次,不能多于12次 ,否则都不匹配。因为使⽤用了 ^ $ ,所以输⼊入的整个字符串都要⽤用来和 \d{5,12} 来匹配,也就是说整个输⼊入 必须是5到12个数字 ,因此如果输⼊入的QQ号能匹配这个正则表达式的话,那就符合要求了。

和忽略⼤大⼩小写的选项类似,有些正则表达式处理⼯工具还有⼀一个处理多⾏行的选项。如果选中了这个选项, ^ $ 的意义就变成了 匹配⾏行的开始处和结束处 。  

如果你想查找元字符本⾝身的话,⽐比如你查找 . ,或者 * ,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使⽤用 \ 来取消这些字符的特殊意义。因此,你应该使⽤用 \. \* 。当然,要查找 \ 本⾝身,你也得⽤用 \\

[aeiou] 就匹配 任何⼀一个英⽂文元⾳音字母 , [.?!] 匹配 标点符号(.或?或!) 。

我们也可以轻松地指定⼀一个字符 范围 ,像 [0-9] 代表的含意与 \d 就是完全⼀一致的: ⼀一位数字 ;同理 [a-z0-9A-Z_] 也完全等同于 \w (如果只考虑英⽂文的话)。

下⾯面是⼀一个更复杂的表达式: \(?0\d{2}[) -]?\d{8} 这个表达式可以匹配 ⼏几种格式的电话号码 ,像(010)88886666 ,或 022-22334455 ,或 02912345678 等。我们对它进⾏行⼀一些分析吧:⾸首先是⼀一个转义字符 \( ,它能出现0次或1次( ? ),然后是⼀一个 0 ,后⾯面跟着2个数字( \d{2} ),然后是 ) - 空格 中的⼀一个,它出现1次或不出现( ? ),最后是8个数字( \d{8} )。 

正则表达式⾥里的 分枝条件 指的是有⼏几种规则,如果满⾜足其中任意⼀一种规则都应该当成匹配,具体⽅方法是⽤用 | 把不同的规则分隔开。 

例子:

0\d{2}-\d{8}|0\d{3}-\d{7} 这个表达式能 匹配两种以连字号分隔的电话号码:⼀一种是三位区号,8位本地号(如010-12345678),⼀一种是4位区号,7位本地号(0376-2233445) 。

\(?0\d{2}\)?[- ]?\d{8}|0\d{2}[- ]?\d{8} 这个表达式 匹配3位区号的电话号码,其中区号可以⽤用⼩小括号括起来,也可以不⽤用,区号与本地号间可以⽤用连字号或空格间隔,也可以没有间隔 。你可以试试⽤用分枝条件把这个表达式扩展成也⽀支持4位区号的。

\d{5}-\d{4}|\d{5} 这个表达式⽤用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者⽤用连字号间隔的9位数字。之所以要给出这个例⼦子是因为它能说明⼀一个问题:使⽤用分枝条件时,要注意各个条件的顺序。如果你把它改成 \d{5}|\d{5}-\d{4} 的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满⾜足了某个分枝的话,就不会去再管其它的条件了。 





 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值