正则表达式是一种描述性的语言,用来匹配字符串。凡是符合规则的字符串,我们认为就是匹配了。
正则表达式并非 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
发现第二个例子匹配结果是
。Python 中
- None
模块
- 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 次 |
表示匹配 3 或 5 或 7 或 8 或 9 中的某一个。像
- [35789]
就匹配任何一个英文元音字母,
- [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']
我们发现常规的切分字符串无法识别连续的空格,但正则可以。
正则表达式还可以提取子串。用
表示的就是要提取的分组。
- ()
是一个简单的 IP 地址匹配表达式。要理解这个表达式,可以按顺序分析:
- (\d{1,3}\.){3}\d{1,3}
匹配 1 到 3 位的数字,
- \d{1,3}
匹配三位数字加上一个英文句号 (这个整体也就是这个分组) 重复 3 次,最后再加上一个一到三位的数字
- (\d{1,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)
…… 表示第 1、2、…… 个子串。
- group(2)
返回所有子串的 tuple。
- groups()
这里由于只有一个分组,所以打印
会报错。
- 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 次以上,但尽可能少重复 |
正则表达式非常强大,本节只是讲解了基础。更多关于正则的知识,大家可以找资料学习。
来源: