什么是正则表达式:
通俗理解:按照一定的规则,从某个字符串匹配出想要的数据。这个规则就是正则表达式。
正则表达式常用匹配规则:
匹配某个字符串:
import re text = 'hello'ret = re.match('he',text)print(ret.group())
点( . )匹配任意的字符:
import re text = 'hello'ret = re.match('.',text)print(ret.group())
但是 . 不能匹配到到换行符。示例代码如下:
import re text = '\n'ret = re.match('.',text)print(ret.group())
\d匹配任意的数字:
import re text = '123' ret = re.match('\d',text) print(ret.group()) ·``` ### \D匹配任意的非数字: ```python import re text = '+++' ret = re.match('\D',text) print(ret.group())
而如果text是数字,那么就匹配不成功了
\w 匹配字母数字及下划线
import re text = 'adfdf' ret = re.match('\w',text) print(ret.group())
\W 匹配非字母数字下划线
import re text = '+++' ret = re.match('\W',text) print(ret.group())
\s 匹配任意空白字符,等价于 [\t\n\r\f]
import retext = ' 'ret = re.match('\s',text)print(ret.group())
\S 匹配任意非空字符
import re text = 'afda' ret = re.match('\S',text) print(ret.group())
\A 匹配字符串开始
import re print(re.findall('\Ahe','hello egon 123'))
\Z 匹配字符串结束,如果存在换行,只匹配换行前的字符串
import re text = ''' hello egon 123''' print(re.findall('123\Z',text))
\n 匹配一个换行符
import re text = ''' ''' print(re.findall('\n',text))
^ 匹配字符串的开头
import re print(re.findall('^he','hello egon 123'))
$ 匹配字符串的末尾
import re text = ''' hello egon 123''' print(re.findall('123$',text))
[...] 用来表示一组字符,单独列出:[amk] 匹配 a,b或c
import re text = 'adlfjdskf' print(re.findall('[aml]',text))
[^...] 不在[]中的字符:[^abc]匹配除了a,b,c之外的字符.
import re text = 'adlfjdskf' print(re.findall('[^dj]',text))
*匹配0个或多个的表达式
import re text = 'adlfaadddjadskf' print(re.findall('ad*',text))
+ 匹配1个或多个的表达式
import re text = 'adlfaadddjadskf' print(re.findall('ad+',text))
? 匹配0个或1个的前面的正则表达式的片段,非贪婪方式
import re text = 'adlfaadddjadskf' print(re.findall('ad?',text))
{n} 精确匹配n个前面表达式
import re text = 'adlfaadddjadskf' print(re.findall('ad{2}',text))
{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
import re text = 'adlfaadddjadskf' print(re.findall('ad{3}',text))
a|b 匹配a或b
import re text = 'adlfaadddjadskf' print(re.findall('a|d',text))
( )匹配括号内的表达式,也表示一个组
import re text = 'adlfahadddjadskf' print(re.findall('(ah)|(ad*)',text))
贪婪模式和非贪婪模式
贪婪模式 import re text = 'abdbsdfdsfj' print(re.findall('a.*d',text)) 非贪婪模式 import re text = 'abdbsdfdsfj' print(re.findall('a.*?d',text))
小案例
1、验证手机号码:手机号码的规则是以1开头,第二可以是34587,后面9位就可以随意了。
import re text = '13533164758' print(re.findall('1[34587]\d{9}',text))
2、验证邮箱:邮箱的规则是邮箱名层是用字母、数字、下划线组成的,然后是 @ 符号,后面就是域名。示例代码如下:
import re text = '2443005004@qq.com' print(re.findall('\w+@\w+\.[a-zA-Z\.]+',text))
3、验证URL:URL的规则是前面是 http或者是https 或者是ftp然后再加上一个冒号 ,再加上一个斜杆,在后面就是可以出现任意非空白字符了。示例代码如下:
import re text = 'http://www.baidu.com/' print(re.match('(http|https|ftp)://[^\s]+',text).group())
4、验证身份证:身份证的规则是:总共有18位,前面的17位都是数字,后面一位可以是数字,也可以是小写x,也可以是大写的X。示例代码如下:
import re text = '445224200202073019' print(re.match('\d{17}[\dxX]',text).group())
转义字符和原生字符串:
在正则表达式中,有些字符是有特殊意义的。因此如果想要匹配这些字符,那么就必须使用反斜杠进行转义。比如 $ 代表的是 以 ... 结尾,如果想要匹配 $ ,那么就必须使用 \ $ 。示例代码如下:
import re text = '88$' print(re.findall('\d+\$',text))
原生字符串:
在正则表达式中 ,\是专门用来转义的。在Python中 \ 也是用来转义的。因此如果想要在普通的字符串中匹配出\ ,那么要给出 四个 \ 。示例代码如下:
import re text = 'ab \c' print(re.findall('\\\\c',text))
因此要使用原生字符串就可以解决这个问题:
import re text = 'ab \c' print(re.findall(r'\\c',text))
re模块常用函数:
match:
从开始的位置进行匹配。如果开始的位置没有匹配到。就直接失败了。示例代码如下:
import re text = 'hello' print(re.match('h',text).group())
如果第一个字母不是h,那么就会失败。示例代码如下:
import re text = 'ahello' print(re.match('h',text).group()) Traceback (most recent call last): File "d:/wampserver64/www/PYTHON/debug.py", line 3, in <module> print(re.match('h',text).group()) AttributeError: 'NoneType' object has no attribute 'group'
如果想要匹配换行的数据,那么就要传入一个 flag = re.DOTALL,就可以匹配换行符了。示例代码如下:
import re text = 'hello\n666' print(re.match('hello.*666',text,re.DOTALL).group())
search:
在字符串中找满足条件的字符。如果找到,就返回第一个满足条件的。
import re text = 'aabcaa' print(re.match('aa',text).group())
分组:
在正则表达式中,可以对过滤到的字符串进行分组。分组使用圆括号的方式。
1、group : 和 group(0)是等价的,返回的是整个满足条件的字符串。
2、groups : 返回的是里面的子组。索引从1开始。
3、group(1) : 返回的是第一个子组,可以传入多个。
示例代码如下:
import re text = 'apple price is $99,orange price is $10' re = re.search(r".*(\$\d+).*(\$\d+)",text) print(re.group()) print(re.group(0)) print(re.group(1)) print(re.group(2)) print(re.group(1,2)) print(re.groups())
findall:
找出所有满足条件的,返回是一个列表。
import re text = 'apple price is $99,orange price is $10' print(re.findall('\$\d+',text))
sub:
用来替换字符串。将匹配到的字符串替换为其他字符串。
import re text = 'apple price is $99,orange price is $10' print(re.sub('\$\d+','0',text))
sub函数的案例,获取拉勾网中的数据:
# -*- coding:utf-8 -*- import re html = ''' <div class="job-detail"> <p>岗位责任:</p><p>承担二维CAD、三维CAD、家居设计软件的开发工作</p><p></p><p>任职要求:</p><p>1.全日制统招本科或硕士学历,取得毕业证书硕士不晚于2019年,本科不晚于2017年,具备英语4级或以上水平,能够阅读英文文档;</p><p>2.具有计算机软件、机械工程、建筑工程、力学或数学等专业背景;</p><p>3.熟练掌握C++语言,具有1年以上C++,MFC,工具软件开发经验;</p><p>4.具有良好的自学能力和独立解决问题的能力,能承受一定工作压力,在指定时间内完成高质量程序;</p> </div> ''' print(re.sub('<.+?>','',html))
split:
使用正则表达式来分割字符串.
# -*- coding:utf-8 -*- import re text = 'hello world ni hao' print(re.split('\W',text))
complie:
对于一些经常要用到的正则表达式,可以使用 complie进行编译,后期在使用的时候就可以直接拿过来用,执行效率会更快。而且 complie 还可以指定 flag = re.VERBOSE , 在写正则表达式的时候可以做好注释。示例代码如下:
# -*- coding:utf-8 -*- import re text = 'the number is 20.50' r = re.compile(r''' \d+ #小数点前的数字 \.? #小数点 \d #小数点后面的数字 ''',re.VERBOSE) ret = re.search(r,text) print(ret.group())
注意:如果匹配模式里面有分组,findall返回分组匹配到的内容,则不会返回匹配模式匹配的内容.
有分组
# -*- coding:utf-8 -*- import re text = 'the number is 20.50' print(re.findall('the\snumber\sis\s(\d+)',text))
无分组
# -*- coding:utf-8 -*- import re text = 'the number is 20.50' print(re.findall('the\snumber\sis\s\d+',text))