正则表达式和re模块:

什么是正则表达式:

通俗理解:按照一定的规则,从某个字符串匹配出想要的数据。这个规则就是正则表达式。

正则表达式常用匹配规则:

匹配某个字符串:

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))