正则表达式
概念: 正则表达式是一种处理文本的工具,和其他工具一样,是人们为了解决某一类专门问题而发明的。正则表达式是正则表达式语言创建的,一些用来匹配和处理文本的字符串。
作用: 正则表达式的作用主要是用于文本匹配和替换。
匹配
一:匹配单个字符串
1、匹配纯文本。
纯文本正则表达式匹配原始文本内对应字符。
如下面文本输入Ben。
hello,my name is Ben.
匹配出来的结果就是:Ben
2、字母大小写问题。
在正则表达式的匹配结果是区分字母的大小写的,Ben只能匹配出Ben,而无法匹配出ben、BEN……等。
3、匹配任意字符。
在正则表达式里,字符 . 可以匹配任何一个单个字符,字母、数字设置是.字符本身。
4、匹配特殊字符。
.字符在正则表达式里有着特殊的含义。如果匹配模式里需要匹配出一个.,就需要在开头加\进行转义,如果要匹配\这需要\\。
二:匹配一组字符
1、字符集合区间
匹配集合区间里面的任何一个字符元素。
如:要匹配文本中na1.xls、na2.xls、sa1.xls
na1.xls
na2.xls
sa1.xls
ca1.xls
ca2.xls
正则表达式:[sn]a.\.xls
常用的字符集合区间
[0-9]等价[0123456789]:可以匹配数字0123456789中的任意一个。
[a-z]:可以匹配a到z的所有小写字母。
[A-Z]:可以匹配A到Z的所有大写字母。
[a-zA-Z]:匹配所有大小写字母。
[0-9a-zA-Z_]:匹配所有字符和数字和下划线。
2、取非匹配。
字符集合通常用来指定一组必须匹配其中之一的字符。但在某些场合,我们需要反过来做,给出一组不需要得到的字符。换句话说就是,除了那个字符集合的字符,其他的字符都可以匹配。
在集合前加元字符^来表明想对一个字符集合进行取非匹配。
如:[^sn]a.\.xls :表示开头字母不是s和n的,第二个字母是a的和后缀是.xls的所有字符串。
三:元字符。
元字符大致可以分为两种:一种是用来匹配文本的,比如是 . ,另外一种是正则表达式所要求的,比如[]。
1、对特殊字符进行转义。
元字符是一些在正则表式里有着特殊含义的字符。因为字符.是一个元字符,他可以用来匹配任何一个单个字符。[表示一个集合的开始,]表示一个集合的结束。
也因为元字符在正则表达式里有着特殊的含义,所以这些字符就无法表达他们本身。如不能使用.来表示.,不能使用[和]来表示[和]。要想表示他们,需要在他们前加上转义字符\,如\.表示.,\[和\]表示[和]。
如:myArray\[[0-9]\] :表示myArray[0]-myArray[9]。
2、常用一些元字符。
①、[\b]回退并删除一个字符
②、\f换页符
③、\n换行符
④、\r回车符
⑤、\t制表符
⑥、\v垂直制表符
Windows使用\r\n文本行结束标签。Unix和Linux只用一个\n。
元字符\d等价[0-9];元字符\D等价[^0-9]
元字符\w等价[a-zA-Z0-9];\W等价[^a-zA-Z0-9]
元字符\s等价[\f\n\r\t\v];\S等价[^\f\n\r\t\v]
十六进制\x ,八进制\0
3、POSIX字符类:
①[:alnum:]等价[a-zA-Z0-9]
[:alpha:]等价[a-zA-Z]
[:blank:]等价[\t ]
④[:cntrl:]等价ASCII控制字符,即0-31,127
[:digit:]等价[0-9]
[:graph:]等价[:print:]-空格
[:lower:]等价[a-z]
[:print:]等价任一可打印字符
[:punct:]等价不是①④的
[:space:]等价[^\f\n\r\t\v]
[:upper:]等价[A-Z]
[:xdigit:]等价[a-fA-F0-9
四:多个匹配
1、元字符+ ,用于字符和集合之后,匹配一个或多个字符(至少一个;不匹配零个字符的情况)。匹配+本身,用\+
2、当在字符集合里,像.和+这样的元字符将被解释为普通字符,不需要转义。
3、*与+用法相同,*匹配字符或集合连续出现零次或多次的情况。
4、元字符? ,只能匹配一个字符(或集合)的零次或一次出现。
5、精确设置匹配次数,元字符{}作用:
①可设置重复匹配次数,如{5},则需要连续5次。
②可设置重复匹配区间{2,4},2-4次
③可设置至少匹配次数{3,},3次以上
6、* 和 + 都是“贪婪型”元字符,其匹配行为多多益善。此时,可使用?后缀将其转化为“懒惰型”版本。如“贪婪型”:* + {n,} ,“懒惰型”:*? +? {n,}?
如:文本This offer is not available to customers living in AK and HI.
贪婪式:正则表达式:<[Bb]>.*[Bb]> 匹配的结果是:AK and HI
懒惰型:正则表达式:<[Bb]>.*?[Bb]> 匹配的结果是:AK 和 HI.
五:位置匹配
1:边界
如果要在这个句子里:The cat scattered his food all over the room.
正则表达式:cat
上面的正则表达式会把所有的cat都找出来,单词scattered里的cat也不会例外。如果我们只是要把句子中的cat单词找出来。办法只有一个,就是使用边界限定符,也就是在正则表达式里用一些特殊的元字符来说明我们想匹配操作在什么位置发生。
(1)单词边界
第一种边界也是最常用的边界是由限定符\b指定的单词边界。\b是用来匹配一个单词的开始和结尾。
在上面的例子里,使用边界限定符输入:
正则表达式:\bcat\b
匹配出来的结果就是单词:cat
注意:正则表达式引擎不懂得英语,更不懂任何人类语言,也不知道什么是单词边界。简单地说:其实\b匹配的是这样的一个位置,这个位置位于一个能够用来构成单词的字符(包括字母,数字和下划线 即\w)和一个不能用来构成单词的字符(也就是\W相匹配的字符)之间。\b只匹配一个位置,不匹配任何的字符,用\bcat\b匹配到的字符串的长度是3个字符。
如果想表明不匹配一个单词边界,使用\B。在下面例子里,使用\B来查找一个前后都不是单词的边界的连字符-。
句子:Please enter the nine-digit id as it appears on your color - coded pass-key.
正则表达式:\b\w+-\w+\b
结果:nine-digit 和 pass-key.
正则表达式:\B-\B
结果:- (匹配前后都不是单词边界的连字符)
注意:如果相匹配一个完整的单词,就必须在你想要匹配的文本的前后都加上\b限定符。
例子:
句子:The captain wore his cap and cape proudly as he sat listening to the recap of his crew saved the men from a capsized vessel.
正则表达式:\bcap
解析:只是匹配以cap开头的单词。结果:captain cap cape capsized
正则表达式:cap\b
解析:只是匹配以cap结尾的单词。结果:cap recap
正则表达式:\bcap\b
解析:匹配cap单词本身。结果:cap
(2)字符串边界
单词边界可以用来进行与单词有关的位置匹配(单词的开头,单词的借宿、整个单词等等……)。字符串边界有类似的用途,只不过是用来进行字符串有关的位置匹配而已(字符串的开头、字符串的借宿、整个字符串等等……)。用来定义字符串边界的元素有两个:一个用来定义字符串的开头 ^ ,另一个用来定义字符串的结尾 $ 。
例子:判断下面是否是合法的xml文档。
This is bad.
xmlns:apachesoap="http://xml.apache.org/xml-soap"
正则表达式:<\?xml.*\?> 能检测到xml的标志,但是因为它能匹配到第二行xml的开头,不能作为检测xml的标准。
修改后的正则表达式:^<\?xml.*\?> 这样只有当xml的的开头在开头第一行才能检测到。
分行匹配模式:
前面讲过^匹配一个字符串的开头,$匹配一个字符串的结尾。但这一结论并非绝对正确,它还有一个例外或者说是一种改变这种行为的方法。
有许多正则表达式都支持使用一些特殊的元字符去改变另外一些元字符行为的做法,用来启用分行匹配模式的(?m)记号就是一个能改变其他元字符行为的元字符序列。分行匹配模式将使得正则表达式引擎把行分隔符当做一个字符串分隔符来对待。在分行匹配模式下,^不仅匹配正常的字符串开通,还将匹配行分割符(换行符)后面的开始位置。
在使用时,(?m)必须出现在整个模式的最前面,就像下面这个例子那样。