您的位置:首页 > 编程语言 > Python开发

Python学习--16 正则表达式

2017-02-11 10:31 183 查看
正则表达式是一种描述性的语言,用来匹配字符串。凡是符合规则的字符串,我们认为就是匹配了。

正则表达式并非Python独有的,它与语言无关。很多语言都支持正则表达式。

我们经常用正则表达式来匹配电子邮件、手机号码、url等等。

来看一个简单的正则表达式,用于匹配手机号码:

^1[35789]\d{9}$

表示匹配以1开头,第二位是3或5或7或8或9,后面9位是数字,且后面必须以9位数字结尾。满足该规则的手机号就说明匹配该正则了。

Python里
re
模块包含所有正则表达式的功能。

注意:由于Python的字符串本身也用
\
转义,所以要特别注意:

s = 'ABC\\'
# 对应的正则表达式字符串变成:'ABC\'

使用Python的
r
前缀,就不用考虑转义的问题了:

s = r'ABC\'
# 对应的正则表达式字符串不变:'ABC\'

上面的正则用Python写则是:

import re

m = re.match(r'^1[35789]\d{9}$', '13271222223')
print(m)

m = re.match(r'^1[35789]\d{9}$', '23271222223')
print(m)


输出:

<_sre.SRE_Match object; span=(0, 11), match='13271222223'>
None

发现第二个例子匹配结果是
None
。Python中
re
模块
match()
方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回
None


所以我们可以写如下判断代码:

import re

if re.match(r'^1[35789]\d{9}$', '13271222223'):
print('ok')
else:
print('not match')


输出:

ok

元字符

\d
属于元字符。

常用的元字符:

代码说明
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束

重复

{9}
属于重复限定符。

常用的限定符:

代码/语法说明
*重复0次或更多次
+重复1次或更多次
?重复0次或1次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

字符类

[35789]
表示匹配3或5或7或8或9中的某一个。像
[aeiou]
就匹配任何一个英文元音字母,
[.?!]
匹配标点符号(.或?或!)。

[0-9]
代表的含意与
\d
就是完全一致的:一位数字;同理
[a-z0-9A-Z_]
也完全等同于
\w
(如果只考虑英文的话)。

使用正则切分字符串

re
模块里的
split
可以代替常规的
split
。示例:

# coding: utf-8

import re

string = 'abc d  e'
print(string.split(' '))

print(re.split(r'\s+', string))


输出:

['abc', 'd', '', 'e']
['abc', 'd', 'e']

我们发现常规的切分字符串无法识别连续的空格,但正则可以。

分组

正则表达式还可以提取子串。用
()
表示的就是要提取的分组。

(\d{1,3}\.){3}\d{1,3}
是一个简单的IP地址匹配表达式。要理解这个表达式,可以按顺序分析:
\d{1,3}
匹配1到3位的数字,
(\d{1,3}\.){3}
匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字
(\d{1,3})


import re

m = re.match(r'(\d{1,3}\.){3}\d{1,3}', '11.22.33.44')
print(m.group(0))
print(m.group(1))

print(m.groups())


输出:

11.22.33.44
33.
('33.',)

group(0)
永远是原始字符串,
group(1)
group(2)
……表示第1、2、……个子串。
groups()
返回所有子串的tuple。

这里由于只有一个分组,所以打印
group(2)
会报错。

贪婪匹配

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。

比如我们要匹配数字102300后面的
0


import re

m = re.match(r'^(\d+)(0*)$', '102300')
print(m.groups())


输出:

('102300', '')

由于贪婪匹配,
\d+
会一直匹配到末尾,把整个数字都匹配了,
0*
就只能匹配空字符串了。我们改改:

import re

m = re.match(r'^(\d+?)(0*)$', '102300')
print(m.groups())


输出:

('1023', '00')

加个
?
就可以让
\d+
采用非贪婪匹配。

懒惰限定符:

代码/语法说明
*?重复任意次,但尽可能少重复
+?重复1次或更多次,但尽可能少重复
??重复0次或1次,但尽可能少重复
{n,m}?重复n到m次,但尽可能少重复
{n,}?重复n次以上,但尽可能少重复
正则表达式非常强大,本节只是讲解了基础。更多关于正则的知识,大家可以找资料学习。

参考:

1、正则表达式30分钟入门教程
http://deerchao.net/tutorials/regex/regex.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: