正则表达式对字符串的逻辑操作主要是对字符串的过滤,用‘元字符’和‘普通字符’组成一个字符串规则对已知的文本或者字符串过滤出自己想要的字符。
're’模块是python中正则表达式的应用
import re
1.正则表达式元字符
-
\ 转义字符,将后边紧跟着的字符变成特殊字符,或将后边的特殊字符变成普通字符
如:在正则表达式中,"\n"换行符,"\“则代表一个普通字符”" -
^ 匹配第一行行首,匹配多行需要传参 flags=re.MULTILINE
-
$ 匹配最后一行行尾,匹配多行需要传参 flags=re.MULTILINE
. 除"\r""\n"外,匹配任意的单个字符,要使"."匹配换行符,flags=re.DOTALL -
| 或,如 “aaa|bbb|ccc”,表示"aaa",“bbb”,"ccc"三选一
-
? 匹配前边的子表达式0次或1次,等价于{0,1}
-
+匹配前边的子表达式1次或多次,等价于{1,}
-
*匹配前边的子表达式0次或多次,,等价于{0,}
-
{} {n}匹配前边的子表达式n次,{n,}匹配前边的子表达式至少n次 即:>= n,{n,m}匹配前边的子表达式n~m次,即:n<= 表达式 <=m
() 分组,从1开始,从左至右数"("为第几组,下标0为全部分组 -
[] 字符集匹配[]中的人一个字符,之匹配一次,如[abc]:表示"a",“b”,"c"三选一。也可以给定范围(必须是连续的才行),如[a-z]:表示a到z任意一个字符。
还可以取反。
注: 要使用元字符本身的普通的含义,要用转义字符转义一下‘\’
分组的用法:
- (\num) 引用指定第几分组的值
- (?P< name>) 指定分组别名"name"
- (?P=name) 引用指定别名的分组的值
- (?: ) 相当于去分组化,变成"与"()子集,如:“abc(?:qqq|www)”–>相当于"abcqqq|abcwww"
2、预定义字符集
- \b 匹配一个单词边界,也就是指单词和空格间的位置,其它特殊字符也可以是单词的边界:如"#","$","&","*"等
- \B 匹配非单词边界
- \d 匹配一个数字字符。等价于[0-9]
- \D 匹配一个非数字字符。等价于 [^0-9]
- \s 匹配任何不可见字符,包括空格、制表符、换页符等,等价于[ \f\n\r\t\v]
- \S 匹配任何可见字符。等价于[^ \f\n\r\t\v]
- \w 匹配包括下划线的任何单词字符。这里的"单词"字符使用Unicode字符集,类似但不等价于“[A-Za-z0-9_]”,还包含汉字等它国字符
- \W 匹配任何非单词字符。这里的"单词"字符使用Unicode字符集,类似但不等价于“[^A-Za-z0-9_]”,还包含汉字等它国字符
3、re模块常用函数
- re.A 或 re.ASCII 使用ASCII字符集进行匹配(不常用)
- re.I 或 re.IGNORECASE 忽略大小写匹配
- re.L 或 re.LOCALE 使用当前预定字符类 \w \W \b \B \s \S 取决于当前区域设定(不常用)
- re.U 或 re.UNICODE 使用Unicode字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性(不常用)
- re.M 或 re.MULTILINE 多行匹配,使"^","$"可以在每一行中都进行匹配
- re.S 或 re.DOTALL 使 “.” 可以匹配换行符"\r","\n"
- re.X 或 re.VERBOSE 去掉正则表达式中的所有空格符(不常用)
(1) re.findall(pattern, string, flags=0)
按照规则匹配整个字符串,返回匹配结果的列表
#普通匹配
re.findall(r'hello','hello world hello')
# 匹配开头
re.findall(r"^hello", "hello world hello")
# 多行匹配开头
re.findall(r'^hello','hello\nhello world',flags=re.MULTILINE)
#匹配结尾
re.findall(r'hello$','hello world hello')
#匹配数字
re.findall(r'\d+','aaa111bbb222ccc333')
#匹配两位数字
re.findall(r'\d{2}','aaa111bbb222ccc333')
#匹配"ab"或"cd"
re.findall(r'ab|cd','aaa111bbb222ccc333')
#匹配"("
re.findall(r'\(','ab(cd')
#想要匹配多个"abc",使用分组时会优先把分组的内容返回
re.findall(r"(abc)+", "abc1abc1abc")
#想要匹配多个"abc",(?:)把分组去掉,变成一个普通的字符串
re.findall(r"(?:abc)+", "abcabcabc")
(2)re.finditer(pattern, string, flags=0)
finditer与findall相似,只不过finditer返回一个迭代器,迭代器中每一个元素都是re.Match对象,通过group()可以获取值
#finditer的使用
r = re.finditer("hello", "hello world hello")
for i in r:
print(i.group())
>>>
hello
hello
(3)re.search(pattern, string, flags=0)
search函数只返回第一个匹配到的结果,成功返回re.Match对象,否则返回None。
# 可以看到只返回了第一个"hello"
re.search(r"hello", "hello world hello")
<_sre.SRE_Match object; span=(0, 5), match='hello'>
re.search(r"hello", "hello world hello").group()
'hello'
# \1 引用分组1的值
re.search(r"(abc) \1", "abc abc").group()
'abc abc'
# (?P=name) 引用分组别名"name"的值
re.search(r"(?P<name>abc) (?P=name)", "abc abc").group()
'abc abc'
re.search(r"(?P<name>zhansan) (?P<age>23)", "zhansan 23").group()
'zhansan 23'
# 分组0--即匹配的结果
re.search(r"(?P<name>zhansan) (?P<age>23)", "zhansan 23").group(0)
'zhansan 23'
# 分组1的值
re.search(r"(?P<name>zhansan) (?P<age>23)", "zhansan 23").group(1)
'zhansan'
# 分组2的值
re.search(r"(?P<name>zhansan) (?P<age>23)", "zhansan 23").group(2)
'23'
# 分组别名name的值
re.search(r"(?P<name>zhansan) (?P<age>23)", "zhansan 23").group("name")
'zhansan'
# 分组别名age的值
re.search(r"(?P<name>zhansan) (?P<age>23)", "zhansan 23").group("age")
'23'
(4)re.match(pattern, string, flags=0)
match从开始处进行匹配,成功返回re.Match对象,否则返回None。类似于于findall代码中的第3行
re.match(r"abc", "abcooooo").group()
(5)re.sub(pattern, repl, string, count=0, flags=0)
sub按照给定的规则将string字符串中的相应的片段替换为repl,count 最多替换的次数,count=0默认为全部替换,返回替换后的字符串
# 将连续的数字变成"$"
re.sub(r"\d+", "$", "aaa1bb2ccc333")
(6)re.subn(pattern, repl, string, count=0, flags=0)
与sub相识,count 最多替换的次数,count=0默认为全部替换,返回 一个元组,下标0为替换后的字符串,下标1成功替换的次数
re.subn(r"\d+", "$", "aaabbccc")
>>>('aaabbccc', 0)
re.subn(r"\d+", "$", "aaa11bb22ccc")
>>>('aaa$bb$ccc', 2)
# 最多替换1次
re.subn(r"\d+", "$", "aaa11bb22ccc", 1)
>>>('aaa$bb$ccc',1)
# 最多替换10次
re.subn(r"\d+", "$", "aaa11bb22ccc", 10)
>>>('aaa$bb$ccc', 2)
(7)re.split(pattern, string, maxsplit=0, flags=0)
通过给定规则,将string进行切割,maxsplit最多切割次数,maxsplit=0默认全部切割,返回
# 没有找到"@",不切割
re.split(r"@", "a#b#c#d#e")
>>>['a#b#c#d#e']
# 按"#"对字符串进行切割
re.split(r"#", "a#b#c#d#e")
>>>['a', 'b', 'c', 'd', 'e']
# 按"#"对字符串进行切割,最多切割2次
re.split(r"#", "a#b#c#d#e", 2)
>>>['a', 'b', 'c#d#e']
(8)re.compile(pattern, flags=0)
返回一个正则表达式的对象
rg = re.compile(r"\d+", flags=0)
re.findall(rg, "a1bb22ccc333")
>>>['1', '22', '333']