首页 > 代码库 > 正则表达式
正则表达式
今天Mayuyu要与大家来学习正则表达式,正则表达式是一个非常有用的工具,它的强大之处就在于处理文本匹配。
说白了正则表达式就是以一种模式去匹配给定文本中所有符合这一模式的字符串,比如[A-Za-z]\w+的含义是第一
个字符必须是字母,它的后面至少跟有一个或者更多由字母或者数字组成的字符。
那么Mayuyu将来一一介绍在正则表达式中常见的特殊字符。
1. |表示一个或操作 例如re1|re2表示匹配re1或者re2
2. .表示任意字符(换行符除外) 例如a.表示字母a后面跟任意一个字符
3. ^表示字符串的开始 例如^Dear表示匹配所有以Dear为开始的字符串
4. $表示字符串的结尾 例如$Dear表示匹配所有以Dear为结尾的字符串
5. *表示匹配前面出现的正则表达式零次或者多次 例如[0-9]*
6. +表示匹配前面出现的正则表达式一次或者多次 例如[0-9]+
7. ?表示匹配前面出现的正则表达式零次或者一次 例如[0-9]?
8. {N}表示匹配前面出现的正则表达式N次 例如[0-9]{3}
9. {M,N}表示匹配重复出现M次到N次的正则表达式 例如[0-9]{1,3}
10. [...]表示匹配字符组里出现的任意一个字符 例如[aeiou]
11. [..x-y..]表示匹配从字符x到y的任意一个字符 例如[0-9]
12. [^...]表示不匹配此字符集中出现的任意一个字符 例如[^aeiou]
13. (...)表示封闭括号中的正则表达式,并保存为子组
14. (*|+|?|{})?表示非贪婪匹配 例如.*?[a-z]
15. \d表示匹配任何数字,其实跟[0-9]一样,\D是\d的反义
16. \w表示匹配任何字母和数字字符,跟[A-Za-z0-9]一样,\W是\w的反义
17. \s表示匹配任何空白字符,和[\n\t\r\v\f]一样,\S是\s的反义
18. \b表示匹配单词边界,\B是\b的反义
上面基本上就是在Python中常用到的特殊字符。我们知道在Python正则表达式编程中要用到re模块,我们要借助
这个模块中的一些方法来完成匹配,那么现在就来介绍在正则匹配中常用到的一些方法。
(1)compile(pattern,flags=0)
对正则表达式模式进行编译,flags是可选标识符,并返回一个regex对象。
(2)match(pattern,string,flags=0)
尝试用正则表达式pattern匹配字符串string,匹配成功返回一个对象,否则饭或None。
(3)search(pattern,string,flags=0)
在字符串string中搜索正则表达式模式pattern的第一次出现,匹配成功返回一个对象,否则返回None。
(4)findall(pattern,string)
搜索正则表达式的所有出现,返回一个列表
(5)finditer(pattern,string)
返回正则表达式所有出现的迭代器
(6)split(pattern,string,max=0)
根据正则表达式把字符串分割为一个列表
(7)sub(pattern,repl,string)
把字符串string中所有正则表达式pattern匹配的地方替换成字符串repl
(8)group()
返回全部匹配对象
(9)groups()
返回一个包含全部匹配的子组的元组
对于上面的一些函数,现在Mayuyu来深入探讨。。。
compile函数
compile函数说白了就是用来提升速度的,我们知道在python中的所有代码最终都会被编译为字节码,然
后才被解释器执行,这样在性能上会有很大的提升,因为利用compile函数编译后得到的一个对象是经过
预编译处理的,这样与普通的正则字符串每次都要编译再执行来比较性能无疑是最好的。
match函数与search函数的区别
它们的区别就是match只匹配以给定的正则表达式开头的字符串,而search是在一个字符串中找一个正则
模式,比如pattern=‘foo‘,string=‘seafood‘,那么如果用match是从string的开头进行匹配,所
以匹配失败,而如果用search则是从string的每一处进行匹配,所以匹配成功。
re的split和string的split函数
我们知道re模块中和字符串中都有一个函数split(),它们的作用类似,不过不一样,前者是根据正则表
达式模式分割字符串,而后者是根据固定的字符串分割,很显然前者的功能更强大。
sub()函数和subn()函数
一般情况下sub()函数有3个参数,分别是pattern,repl和string,表示把string字符串中所有与正
则表达式pattern匹配的字符串替换为repl。而subn()函数跟sub()几乎一样,只是多返回一个表示字
符串替换的次数的数字。
嗯,介绍完上面的各种函数后,貌似Mayuyu还漏掉了两个重要内容。。。(原始字符串和贪婪匹配)
好吧,先来介绍原始字符串。。。
为什么需要原始字符串?其实原始字符串的产生是由于正则表达式的存在,因为ASCII字符和正则表达式的一些字符
会产生冲突,比如‘\b‘,在ASCII字符中表示退格键,但是‘\b‘同时也是一个正则表达式的特殊字符,代表匹配一
个单词边界。
如果出现上述情况,实际上我们在正则表达式中我们完全可以通过一个反斜杠对它进行转义,也就是这样写‘\\b‘,
但是这样做会把问题复杂化,当有多个这样的特殊字符出现时,可能会把你搞得天昏地暗,血肉模糊。所以这里我们
就引入了原始字符串。如下比较:
>>> import re >>> m = re.match(‘\bblow‘,‘blow‘) >>> if m is not None: m.group() >>> m = re.match(‘\\bblow‘,‘blow‘) >>> if m is not None: m.group() ‘blow‘ >>> m = re.match(r‘\bblow‘,‘blow‘) >>> if m is not None: m.group() ‘blow‘ >>>
所以在Python的正则表达式中,我们把模式串设置为原始字符串是一个很好的习惯,这样不会引起不必要的错误。
接下来Mayuyu带大家继续讨论另一个重要的问题,贪婪匹配。
好吧,Mayuyu先说什么是贪婪匹配吧,在正则表达式中默认是贪婪匹配的,也就是说,如果正则表达式中使用到通
配字,那么它在按照从左到右的顺序求值时,会尽量抓取满足匹配的最长字符串,先举个例子吧。比如下面的字符串
‘Mayuyu is from HongKong,her birthday is 1994-03-26‘
我们想要提取出Mayuyu的生日,那么我们貌似可以用如下语句:
>>> import re >>> str=‘Mayuyu is from HongKong,her birthday is 1994-03-26‘ >>> pattern=‘.+(\d+-\d+-\d+)‘ >>> re.match(pattern,str).group(1) ‘4-03-26‘ >>>
哎呀,得到的不是Mayuyu的生日,很明显不符合要求哦,那么实际上也说了,因为贪婪匹配的原因,前面的通配符
一直匹配到9,因为9后面的4是必须要有的,那么最终就得到了这样的错误结果,所以我们必须解除这样的贪婪匹配
方式,怎么解除? 不用担心啦,操作符‘?‘就是用来解除贪婪匹配的,这个操作符用在‘*‘,‘+‘,‘?‘的后面,作用
是要求正则表达式引擎匹配的字符越少越好,嗯,这样我们对上述代码稍加修改就能得到Mayuyu想要的结果了。
>>> str=‘Mayuyu is from HongKong,her birthday is 1994-03-26‘ >>> pattern=‘.+?(\d+-\d+-\d+)‘ >>> re.match(pattern,str).group(1) ‘1994-03-26‘ >>>
嗯 ,至此,Mayuyu基本将Python的正则表达式讲述完毕!!!