Python正则表达式和模式匹配
一、正则表达式简介
1.1 用途
- 表达文本类型的特征(病毒、特征等)
- 同时查找或替换一组字符
- 匹配字符串的全部或部分(最重要的功能)
1.2 常用操作符
正则表达式由字符和操作符(元字符)构成。
操作符 | 说明 | 实例 |
---|---|---|
. | 表示任何单个字符 | |
[ ] | 字符集,对单个字符给出取值范围 | [abc] 表示 a、b、c,[a-z] 表示 a 到 z 的单个字符 |
[^] | 非字符集,对单个字符给出排除范围 | [^abc] 表示非 a、b、c 的单个字符 |
* | 前一个字符0次或无限次扩展 | abc* 表示 ab、abc、abcc... |
+ | 前一个字符1次或无限次扩展 | abc+ 表示 abc、abcc... |
? | 前一个字符0次或1次扩展 | abc? 表示 ab 和 abc |
| | 操作符两侧表达式任意一个 | abc|def 表示 abc 和 def |
{m} | 扩展{}前面的一个字符 | ab{2}c 表示 abbc |
{m,n} | 扩展前一个字符 m 到 n 次(包含 m、n) | ab{1,2}c 表示 abc、abbc |
^ | 匹配字符串开头 | ^abc 表示以 abc 开头的字符串 |
\(|匹配字符串结尾|`abc\)表示以 abc 结尾的字符串| |( )|分组标记,且 ( )内只能使用 |
| (abc)表示 abc, (abc |
def)表示 abc、def| |\d|数字,等价于 [0-9]|| |\w|单词字符,等价于 [A-Za-z0-9_]` |
(?P |
可以使匹配的字符串可以在后面的程序中通过组名符号 |
看下面的代码示例。官网说明请访问 Regular Expression HOWTO |
1 | import re |
1.3 经典正则表达式实例
表达式 | 含义 |
---|---|
^[A-Za-Z]+$ |
由26个字母组成的字符串 |
^[A-Za-z0-9]+$ |
由26个字母和数字组成的字符串 |
^-?\d+$ |
整数形式的字符串 |
^\d+$ |
正整数形式的字符串 |
[1-9]\d{5} |
中国境内邮政编码,6位(这个有问题的,起码可以是0开头) |
[\u4e00-\u9fa5] |
匹配中文字符 |
\d{3}-\d{8}|\d{4}-\d{7} |
中国境内电话号码 |
1.4 匹配 IP 地址
IP 地址分4段,每段的取值范围是0-255。正则表达式精确表示形式:
1 | 0-99:[1-9]?\d |
1.5 贪婪匹配和最小匹配
贪婪匹配,Re 库默认采用贪婪匹配,即输出匹配最长的子串
最小匹配,输出匹配最短的子串
最小匹配操作符
操作符 | 说明 |
---|---|
*? | 前一个字符0次或无限次扩展,返回最小匹配 |
+? | 前一个字符1次或无限次扩展,返回最小匹配 |
?? | 前一个字符0次或1次扩展,返回最小匹配 |
{m,n}? | 扩展前一个字符 m 至 n 次(含 n),返回最小匹配 |
二、Re 库的使用
Re 库是 Python 的标准库,主要用于字符串匹配。调用方式:import re
2.1 正则表达式的表示类型
- raw string 类型(原生字符串类型),是不包含对转义符再次转义的字符。表示为
r'text'
- string 类型,更加繁琐。例如 raw string 类型表示电话号码
\d{3}-\d{8}|\d{4}-\d{7}
,string 类型则需要增加转义符\\d{3}-\\d{8}|\\d{4}-\\d{7}
2.2 Re 库主要功能函数
函数 | 说明 |
---|---|
re.search() |
在一个字符串中搜索匹配正则表达式的第一个位置,返回 match 对象 |
re.match() |
从一个字符串的开始位置匹配正则表达式,返回 match 对象 |
re.findall() |
搜索字符串,以列表类型返回全部能匹配的子串 |
re.split() |
将一个字符串按照正则表达式匹配结果进行分割,返回列表类型(正则表达式作为分隔符) |
re.finditer() |
搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是 match 对象 |
re.sub() |
在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串 |
2.2.1 语法
1 | re.search(pattern,string,flags=0) |
说明:
pattern
:正则表达式的字符串或原生字符串表示pattern
中经常会使用一个原始字符串标志 r,可以确保 Python 不处理字符串中的转义字符(如、)
string
:待匹配字符串flags
:正则表达式使用时的控制标记maxsplit
:最大分割数,剩余部分作为最后一个元素输出repl
:替换匹配字符串的字符串,用 repl 替换 patterncount
:匹配的最大替换次数
2.2.2 常用控制标记
flags常用标记 | 说明 |
---|---|
re.I ,re.IGNORECASE |
忽略正则表达式的大小写,[A-Z]能匹配 a-z |
re.M ,re.MULTILINE |
正则表达式中的^能够将给定的字符串的每行当做匹配开始 |
re.S ,re.DOTALL |
正则表达式中 . 操作符能匹配所有字符,默认匹配除换行外的所有字符 |
注意:对匹配的结果进行使用时,必须用 if 语句进行判断匹配结果(match 对象或列表)是否为空 ,否则对空字符串进行操作会报错“ ”
示例代码:14’25’’
2.3 Re 库的两种使用方法
2.3.1 函数式用法
前面所讲的,都是 Re 库的第一种用法——函数式用法:一次性操作
1 | Rst = re.search(r'\d{3}-\d{8}|\d{4}-\d{7}’,'我的电话 010-02145324') |
2.3.2 面向对象用法
现在我们来介绍第二种用法——面向对象用法:编译后多次使用
比如前面的例子中,用面向对象的写法如下所示:
1 | patt = re.compile(r'\d{3}-\d{8}|\d{4}-\d{7}') |
将正则表达式的字符串形式编译成正则表达式对象:
1 | regex = re.compile(pattern,flags) |
面向对象用法的功能函数由于函数用法中的pattern 已经编译成 regex,所以下面6个函数使用时需要去掉 pattern 参数。即 regex.search(string,flags)
函数 | 说明 |
---|---|
regex.search() |
在一个字符串中搜索匹配正则表达式的第一个位置,返回 match 对象 |
regex.match() |
从一个字符串的开始位置匹配正则表达式,返回 match 对象 |
regex.findall() |
搜索字符串,以列表类型返回全部能匹配的子串 |
regex.split() |
将一个字符串按照正则表达式匹配结果进行分割,返回列表类型(正则表达式作为分隔符) |
regex.finditer() |
搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是 match 对象 |
regex.sub() |
在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串 |
三、Re 库的 match 对象
re 库运行后返回的是 match 对象。
3.1 match 对象的属性
属性 | 说明 |
---|---|
.string |
待匹配的文本 |
.re |
匹配时使用的 pattern 对象(正则表达式) |
.pos |
正则表达式搜索文本的开始位置 |
.endpos |
正则表达式搜索文本的结束位置 |
3.2 match 对象的方法
方法 | 说明 |
---|---|
.group(0) |
获得匹配后的字符串。(一般使用就这个 .group(0) 就足够了) |
.start() |
匹配字符串在原始字符串的开始位置 |
.end() |
匹配字符串在原始字符串的结束位置 |
.span() |
返回(.start(), .end()) |
示例: