Python(八)

re模块的使用

链接:正则表达式

match(正则表达式,待匹配字符串(起始位置))

  • 用于正则匹配检查,如果待匹配字符串能够匹配正则表达式,则match方法返回匹配对象,否则返回None
  • 采用从左往右逐项比较匹配

实例1:

1
2
3
4
5
6
##例如:新的邮箱手机号验证格式是否正确,用正则表达式对于格式验证

import re
rs = re.match('chinahadoop','chinahadoop.cn')
print(rs)
print(rs.span())

结果:

1
2
<_sre.SRE_Match object; span=(0, 11), match='chinahadoop'>
(0, 11) #匹配目标的位置

group()方法

  • 用来返回字符串的匹配部分

实例2:

1
2
3
4
5
6
7
##例如:新的邮箱手机号验证格式是否正确,用正则表达式对于格式验证

import re
rs = re.match('chinahadoop','chinahadoop.cn')
print(rs)

print(rs.group())

结果:

1
2
<_sre.SRE_Match object; span=(0, 11), match='chinahadoop'>
chinahadoop

字符匹配、数量表示、边界表示

单字符匹配

Ps: ‘\d’ ‘\s’’\w’经常使用

实例3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import re


##作用对文本进行处理的时候

# . 是匹配除\n之外的任意单个字符
rs = re.match('.','a') #第一个参数正则表达式
print(rs.group())

rs = re.match('.','1')
print(rs.group())

#单字符匹配
rs = re.match('...','abc')
print(rs.group())

# rs = re.match('...','\n')
# print(rs) ###最后一个会报错

结果:

1
2
3
4
a
1
abc
None

实例4:

1
2
3
4
5
6
7
8
9
10
11
12
13
import re

# \s--任意空白字符,如空格,制表符'\t'、换行符'\n'
rs = re.match('\s','\t')
print(rs)
rs = re.match('\s','\n')
print(rs)
rs = re.match('\s',' ')
print(rs)

#\S
rs = re.match('\S\S\S','abc')
print(rs)

结果:

1
2
3
4
<_sre.SRE_Match object; span=(0, 1), match='\t'>
<_sre.SRE_Match object; span=(0, 1), match='\n'>
<_sre.SRE_Match object; span=(0, 1), match=' '>
<_sre.SRE_Match object; span=(0, 3), match='abc'>

实例5:

1
2
3
4
5
6
7
8
9
10
import re

rs = re.match('[Hh]','hello')
print(rs)

rs = re.match('[0123456789]','32')
print(rs)
#等价于上面的代码
rs = re.match('[0-9],'32')
print(rs)

结果:

1
2
3
<_sre.SRE_Match object; span=(0, 1), match='h'>
<_sre.SRE_Match object; span=(0, 1), match='3'>
<_sre.SRE_Match object; span=(0, 1), match='3'>

多字符匹配(单字符+数量表示)

实例6:

1
2
3
4
5
6
# \d只匹配数字
# *--任意次
import re

rs = re.match('1\d*','1234')
print(rs.group())

结果:

1
1234

实例7:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#+至少出现一次
rs = re.match("\d+","abc")
print(rs)
rs = re.match("\d+","1abc")
print(rs)
rs = re.match("\d+","123345abc")
print(rs)

print('=====分割线======')

#?至多1次(0次或者1次)

rs = re.match("\d?","abc")
print(rs)
rs = re.match("\d?","123abc")
print(rs)
print('=====分割线======')

#{m}固定次数
rs = re.match("\d{3}","123abc")
print(rs)
#{m,}
rs = re.match("\d{1,}","123467abc")#等价于+至少一次
print(rs)

#{m,n}
rs = re.match("\d{0,1}","abc") #等价于?至多一次
print(rs)

print('=====分割线======')

#匹配11位的手机号
#11位,第一位1,第二位3,5,7,8 第3位到第11为0到9的数字

rs = re.match("1[3578]\d{9}","13623198765")
print(rs)
rs = re.match("1[3578]\d{9}","14623198765")#非法手机号
print(rs)
rs = re.match("1[3578]\d{9}","13623198765abc")#非法手机号
print(rs)

print('=====分割线======')

#转义字符处理
# str1 = "hello\\world"
# print(str1)
# str2 = "hello\\\\world"
# print(str2)

print('=====分割线======')

str3 = r"hello\\world" #原生字符串 ##实际str3 = 'hello\\\\world'
print(str3)
# rs = re.match("\w{5}\\\\\\\\\w{5}",str3)
# print(rs)
rs = re.match(r"\w{5}\\\\\w{5}",str3)
print(rs)

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
None
<_sre.SRE_Match object; span=(0, 1), match='1'>
<_sre.SRE_Match object; span=(0, 6), match='123345'>
=====分割线======
<_sre.SRE_Match object; span=(0, 0), match=''>
<_sre.SRE_Match object; span=(0, 1), match='1'>
=====分割线======
<_sre.SRE_Match object; span=(0, 3), match='123'>
<_sre.SRE_Match object; span=(0, 6), match='123467'>
<_sre.SRE_Match object; span=(0, 0), match=''>
=====分割线======
<_sre.SRE_Match object; span=(0, 11), match='13623198765'>
None
<_sre.SRE_Match object; span=(0, 11), match='13623198765'>
=====分割线======
=====分割线======
hello\\world
<_sre.SRE_Match object; span=(0, 12), match='hello\\\\world'>

边界表示

字符串与单词边界

应用场景:是否要加边界,区别:比如用户注册的时候验证他输入的邮箱就要加边界,限制他写入的是合法的邮箱,再比如处理文本数据的时候提取邮箱信息,有可能文本里的数据就是非法的,只是为了提取出邮箱,就不用加边界。

实例8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#边界表示
# $字符串结尾
import re

rs = re.match('1[3578]\d{9}$','13623456767')
print(rs.group())

rs = re.match('1[3578]\d{9}$','13623456767abc')
print(rs)

#邮箱匹配

rs = re.match('\w{3,10}@163\.com$','hello_124@163.com') # \ 是转义字符(将特殊的符号转化为普通的字符),\.就是一个普通的点
print(rs)

print('=====分割线=====')

#单词边界,用来查找关键字
# \b
rs = re.match(r'.*\bpython\b','hi python hello')
print(rs)

# \B
# 非单词边界,查找字符串中重点的某些字符
rs = re.match(r'.*\Btho\B','hi python hello') #如果有边界字母的话,就会返回none
print(rs)

结果:

1
2
3
4
5
6
7
13623456767
None
<_sre.SRE_Match object; span=(0, 17), match='hello_124@163.com'>
=====分割线=====

<_sre.SRE_Match object; span=(0, 9), match='hi python'>
<_sre.SRE_Match object; span=(0, 8), match='hi pytho'>

匹配分组

实例9:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#匹配分组
#匹配0-100之间的数字

import re
rs = re.match(r'[1-9]\d?$|100$|0$','100')
print(rs)
rs = re.match(r'[1-9]\d?$|100$|0$','85')
print(rs)
rs = re.match(r'[1-9]\d?$|100$|0$','0')
print(rs)
rs = re.match(r'[1-9]$\d?$|100$|0$','0')
print(rs)
print('=======分割线======')

rs = re.match('\w{3,10}@(163|qq|outlook)\.com$','hello@163.com')
print(rs)
print('=======分割线======')

#\NUM
html_str = '<head><title>python</title></head>'

rs = re.match(r'<(.+)><(.+)>.+</\2></\1>',html_str)
print(rs)
print('=======分割线======')
#(?P<name>)和(?P=name)分组起别名 #成对出现的标签,适合用分组起别名方法
html_str = '<head><title>python</title></head>'

rs = re.match(r'<(?P<g1>.+)><(?P<g2>.+)>.+</(?P=g2)></(?P=g1)>',html_str)
print(rs)

结果:

1
2
3
4
5
6
7
8
9
10
<_sre.SRE_Match object; span=(0, 3), match='100'>
<_sre.SRE_Match object; span=(0, 2), match='85'>
<_sre.SRE_Match object; span=(0, 1), match='0'>
<_sre.SRE_Match object; span=(0, 1), match='0'>
=======分割线======
<_sre.SRE_Match object; span=(0, 13), match='hello@163.com'>
=======分割线======
<_sre.SRE_Match object; span=(0, 34), match='<head><title>python</title></head>'>
=======分割线======
<_sre.SRE_Match object; span=(0, 34), match='<head><title>python</title></head>'>

正则表达式的高级用法

  • 从左到右在字符串的任意位置搜索第一次出现匹配给定正则表达式的字符

实例10:

1
2
3
4
import re
# search
rs = re.search('car','haha car carbal abcar carbal')
print(rs)

结果:

1
<_sre.SRE_Match object; span=(5, 8), match='car'>

findall

  • 在字符串中查找所有匹配成功的组,返回匹配成功的结果列表

实例11:

1
2
3
4
5
6
7
8
9
#findall
rs = re.findall('car','haha car carbal abcar carbal')
print(rs)
print('=====分割线======')

mail_str = 'zhangsan:helloworld@163.com,li:123456@qq.cn'
list = re.findall(r'\w{3,20}@(163|qq)\.(com|cn)',mail_str)
print(list)
print('=====分割线======')

结果:

1
2
3
['car', 'car', 'car', 'car']
=====分割线======
[('163', 'com'), ('qq', 'cn')]

finditer

  • 在字符串中查找所有正则表达式匹配成功的字符串,返回iterator迭代器

实例12:

1
2
3
4
#finditer
itor = re.finditer(r'\w{3,20}@(163|qq)\.(com|cn)',mail_str)
for it in itor:
print(it.group())

结果:

1
2
helloworld@163.com
123456@qq.cn

sub

  • 将匹配到的数据使用新的数据替换

实例13:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# sub
str_list = 'java python c cpp java'
rs = re.sub(r'java','python',str_list)
print(rs)
print('=====分割线======')

str_test = "apple=5,banana=3,orange=2"
def update_price(result):
price = result.group()
new_price = int(price) + 1
new_price = str(new_price)
return new_price
rs = re.sub(r"\d+",update_price,str_test)
print(rs)

结果:

1
2
3
python python c cpp python
=====分割线======
apple=6,banana=4,orange=3

split

  • 根据指定的分隔符切割字符串,返回切割之后的列表

实例14:

1
2
3
4
5
#split

price_list = str_test.split(',')
for price in price_list:
print(price)

结果:

1
2
3
apple=5
banana=3
orange=2

贪婪与非贪婪模式

贪婪模式

  • 正则表达式引擎默认是贪婪模式,尽可能多的匹配字符

实例15:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import re

#贪婪模式
rs = re.findall(r'hello\d*','hello12345')
print(rs)

rs = re.findall(r'hello\d+','hello12345') #至少出现一次
print(rs)

rs = re.findall(r'hello\d?','hello12345') #至多出现一次
print(rs)

rs = re.findall(r'hello\d{2,}','hello12345') #至少2次以上
print(rs)

rs = re.findall(r'hello\d{1,3}','hello12345') #1-3次
print(rs)

结果:

1
2
3
4
5
['hello12345']
['hello12345']
['hello1']
['hello12345']
['hello123']

非贪婪模式

  • 与贪婪模式相反,尽可能少的匹配字符
  • 在表示数量的’*’,’?’,’+’,’{m,n}’符号后面加上?,使贪婪变成非贪婪

实例16:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import re
#非贪婪模式
rs = re.findall(r'hello\d*?','hello12345')
print(rs)

rs = re.findall(r'hello\d+?','hello12345') #至少出现一次
print(rs)

rs = re.findall(r'hello\d??','hello12345') #至多出现一次
print(rs)

rs = re.findall(r'hello\d{2,}?','hello12345') #至少2次以上
print(rs)

rs = re.findall(r'hello\d{1,3}?','hello12345') #1-3次
print(rs)

结果:

1
2
3
4
5
['hello']
['hello1']
['hello']
['hello12']
['hello1']

-------------本文结束感谢您的阅读-------------


本文标题:Python(八)

文章作者:HuXuzhe

发布时间:2018年07月08日 - 15:07

最后更新:2018年11月21日 - 15:11

原始链接:https://huxuzhe.github.io/2018/07/08/Python-八/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

HuXuzhe wechat
关注微信公众号:"AI数据分析算法",轻轻扫一扫,加入我们的AI_LEGENDS !
坚持原创,您的支持将鼓励我继续创作!
0%