Python-正则(regex)
即文本的高级匹配模式,提供搜索,替代等功能。其本质是一系列由特殊符号组成的字串,这个字串即正则表达式。
由普通字符和特殊符号组成字符串,通过描述字符的重复和位置等行为,达到匹配某一类字符串的目的
概述
动机
- 文本处理已经成为计算机的常见工作之一
- 对文本内容的搜索,定位,提取是逻辑比较复杂的工作
- 为了快速解决上述问题,产生了正则表达式技术
定义
即文本的高级匹配模式,提供搜索,替代等功能。其本质是一系列由特殊符号组成的字串,这个字串即正则表达式。
匹配原理
由普通字符和特殊符号组成字符串,通过描述字符的重复和位置等行为,达到匹配某一类字符串的目的
目标
- 熟练掌握正则表达式符号
- 实现基本的文本搜索,定位,提取,理解正则用法
- 能够适用re模块操作正则表达式
特点
- 方便文本处理
- 支持语言众多
- 使用灵活多样
基础实践
re模块简单实用
1 | re.findall(pattern, string) |
功能: 使用正则表达式匹配目标字符串内容
参数
- pattern 正则表达式
- string 目标字符串
返回值: 列表,列表中为匹配到的内容
元字符的使用
普通字符
元字符 : a
b
c
匹配规则: 每个字符匹配对应的字符
1 | re.findall("hello","hello world") |
1 | re.findall("你好","你好北京") |
或
元字符: |
匹配规则: 匹配 | 两边任意一个正则表达式
1 | re.findall("ab|cd","abcdefghialkjasbab") |
匹配单个字符
元字符: .
匹配规则: 匹配除换行外的任意字符
1 | f.o --> foo fao f@o f o |
1 | re.findall("f.o","foo is not fao") |
匹配开始位置
元字符 : ^
匹配规则:匹配目标字符串的开头位置
1 | re.findall("^Tom","Tom is a boy") |
匹配结束位置
元字符 : $
匹配规则 : 匹配字符串的结束位置
1 | re.findall("Tom$","hi Tom") |
匹配重复 *
元字符 : *
匹配规则: 匹配前面的字符出现0次或多次
1 | fo* --> fooooooooo f fo |
1 | re.findall("fo*","fadsfafoooafo") |
匹配重复 +
元字符 : +
匹配规则: 匹配前面的字符出现1次或多次
1 | fo+ --> fo fooooo |
1 | re.findall("fo+","fadsfafoooafo") |
匹配重复 ?
元字符 : ?
匹配规则: 匹配前面的字符出现0次或1次
1 | fo? --> f fo |
1 | re.findall("fo?","fasdffoafooooo") |
匹配重复 {n}
元字符 : {n}
匹配规则: 匹配指定的重复次数
1 | fo{3} --> fooo |
1 | re.findall("fo{2}","fasdffoafooooo") |
匹配重复 {m,n}
元字符 : {m,n}
匹配规则 : 匹配前面的正则表达式 m–n次
1 | fo{2,4} --> foo fooo foooo |
1 | re.findall("fo{2,4}","fasdfofoooafooooo") |
匹配字符集合
元字符: [字符集]
匹配规则 : 匹配任意一个字符集中的字符
1 | [abc123] a b c 1 2 3 |
1 | re.findall("^[A-Z][a-z]*","Boy") |
匹配字符集
元字符 : [^...]
匹配规则 :字符集取非,除列出的字符之外任意一个字符
1 | [^abc] --> 除a b c之外任意字符 |
1 | re.findall("[^ ]+","a little boy") |
匹配任意(非)数字字符
元字符 : \d
\D
匹配规则:
\d
匹配任意数字字符[0-9]
\D
匹配任意非数字字符[^0-9]
1 | re.findall("1\d{10}","18888886666") |
匹配任意(非)普通字符
元字符 : \w
\W
匹配规则:
\w
普通字符[_0-9a-zA-Z]
也能匹配普通汉字\W
非普通字符
1 | re.findall("\w+","hello#nihao%asdf@adsgdfg!df&") |
1 | re.findall("\W+","hello#nihao%asdf@adsgdfg!df&") |
匹配任意(非)空字符
元字符 :
\s
匹配任意空字符[ \r\t\n\v\f]
\S
匹配任意非空字符
1 | re.findall("\w+\s+\w+","hello world") |
1 | re.findall("\S+","hello this is tom") |
空格也属于空字符
匹配字符串位置
元字符 : \A
\Z
匹配规则:
\A
匹配字符串开头位置^
\Z
匹配字符串结尾位置$
绝对匹配 : 正则表达式要完全匹配目标字符串内容
在正则表达式开始和结束位置加上^
$
(或者\A
\Z
)。这样正则表达式必须匹配整个目标字符串才会有结果
1 | re.findall("\A\d+\Z","123445") |
匹配(非)单词边界
元字符 : \b
\B
匹配规则 :
\b
匹配单词边界位置 普通字符和非普通字符交界认为是单词边界\B
匹配非单词边界位置
1 | re.findall(r"num\b","num#asdf#") |
1 | re.findall(r"num\b","numasdf#") |
元字符总结
匹配单个字符 : a
.
\d
\D
\w
\W
\s
\S
[...]
[^...]
匹配重复 : *
+
?
{n}
{m,n}
匹配位置 : ^
$
\A
\Z
\b
\B
其他 : |
()
\
正则表达式转义
正则中的特殊符号:
.
*
+
?
^
$
[]
{}
()
|
\
正则表达式如果匹配特殊字符需要加 \
表达转义
1 | 正则 目标字符串 |
1 | pattern string |
raw字串 : 原始字符串对内容不解释转义,就表达内容原 本意义
贪婪与非贪婪
贪婪模式 : 正则表达式的重复匹配总是尽可能多的向后匹配更多内容
*
+
?
{m,n}
非贪婪(懒惰模式) : 尽可能少的匹配内容
贪婪 —> 非贪婪 *?
+?
??
{m,n}?
1 | re.findall(r"ab+?","abbbbbbbb") |
1 | re.findall(r"ab??","abbbbbbbb") |
正则表达式的子组
可以使用()
为正则表达式建立子组,子组可以看做是正则表达式内部操作的一个整体
子组是在正则表达式整体匹配到内容的前提下才会发挥作用,它不影响正则表达式整体去匹配目标内容这一原则
子组使用
- 作为内部整体可以改变某些元字符的行为
1 | re.search(r"(ab)+\d+","ababab1234").group() |
1 | re.search(r"\w+@\w+\.(com|cn)","abc@123.com").group() |
- 子组在某些操作中可以单独提取出匹配内容
1 | re.search(r"(https|http|ftp)://\S+","https://www.baidu.com").group(1) |
子组使用注意事项
- 一个正则表达式中可以有多个子组
- 子组一般由外到内,由左到右称之为第一,第二 第三。。。。子组
- 子组不能重叠,嵌套也不宜很多
search 只能匹配一个结果
捕获组 和 非捕获组
1 | 格式 : (?P<name>pattern) |
1 | e.g. |
作用 : 可以通过组名更方便获取某组内容
正则表达式设计原则
- 正确性 ,能正确匹配到目标内容
- 排他性 ,除了要匹配的内容,尽可能不会匹配与到其他内容
- 全面性 ,需要对目标的各种情况进行考虑,做到不遗漏
re模块
compile
用来生成正则表达式对象
regex = compile(pattern,flags=0)
- 功能 : 生成正则表达式对象
- 参数 :
- pattern 正则表达式
- flags 功能标志位,丰富正则表达式的匹配功能
- 返回值 : 返回正则表达式对象
findall
re模块调用
re.findall(pattern,string,flags)
- 功能 :从目标字符串查找正则匹配内容
- 参数 :
- pattern 正则表达式
- string 目标字符串
- flags 标志位
- 返回值 : 返回匹配到的内容 如果正则有子组则只返回子组对应内容
正则对象调用
regex.findall(string,pos,endpos)
- 功能 :从目标字符串查找正则匹配内容
- 参数 :
- string 目标字符串
- pos 匹配目标的起始位置
- endpos 匹配目标的终止位置
- 返回值 : 返回匹配到的内容 如果正则有子组则只返回子组对应内容
split
正则表达式所匹配的内容,做字符串的切割
re.split(pattern,string,flags = 0)
- 功能:根据正则匹配内容切割字符串
- 参数: pattern string flags
- 返回值: 返回列表,列表中为切割的内容
sub
使用一个字符串去替换目标字符串被正则表达式匹配到的内容
re.sub(pattern,replaceStr,string,max,flags)
- 功能: 替换正则匹配到的目标子串部分
- 参数:
- pattern
- replaceStr : 要替换的内容
- string
- max 最多替换几处 默认全部替换
- flags
- 返回值 : 返回替换后的字符串
subn
使用一个字符串去替换目标字符串被正则表达式匹配到的内容
re.subn(pattern,replaceStr,string,max,flags)
- 功能: 替换正则匹配到的目标子串部分
- 参数:
- pattern
- replaceStr : 要替换的内容
- string
- max 最多替换几处 默认全部替换
- flags
- 返回值 : 返回一个元组,为实际替换了几处和替换后的字符串
sub 和 subn区别
- sub返回替换后的字符串
- subn返回替换了几处
finditer
相比findall返回一个迭代对象
re.finditer(pattern,string,flags)
- 功能: 使用正则表达式匹配目标字符串
- 参数: pattern string flags
- 返回值: 返回一个迭代对象,迭代到的内容是一个match对象
fullmatch
相当于在最前面写一个^
,最后面写一个$
, 只匹配到一处,返回一个match对象
fullmatch(pattern,string,flags)
- 功能: 完全匹配目标字符串
- 参数: pattern,string,flags
- 返回值:返回匹配到的match对象 如果没匹配成功返回None
match
相当于只匹配到开头,返回一个match对象
match(pattern,string,flags)
- 功能: 从开头位置匹配目标字符串
- 参数: pattern,string,flags
- 返回值:返回匹配到的match对象 如果没匹配成功返回None
search
search(pattern,string,flags)
- 功能: 正则表达式匹配目标字符串,只匹配第一处
- 参数: pattern,string,flags
- 返回值:返回匹配到的match对象 如果没匹配成功返回None
compile对象属性:
flags : 标志位
pattern : 正则表达式
groups: 有多少子组
groupindex : 捕获组形成组名和序列号的字典
组名为键,第几组为值
match对象属性
属性变量
1 | pos 匹配目标字符串的开始位置 |
属性方法
1 | span() 匹配内容的开始位置 |
1 | group() |
1 | groupdict() 获取捕获组名作为键,对应内容作为值的字典 |
flags 参数的使用
re.compile re.findall re.search re.match
re.finditer re.fullmatch re.sub re.subn re.split
上面这些方法都有flags参数
作用: 辅助正则表达式,丰富匹配结果
1 | I == IGNORECASE 匹配时忽略字母的大小写 |
使用多个标志位使用按位或连接
1 | e.g. |