re模块操作
在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re
re.match
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none
#coding=utf-8
# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串,标志位)
# 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
正则表达式修饰符 - 可选标志
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
修饰符 | 描述 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解 |
示例: 匹配以itcast开头的语句
import re
result = re.match("itcast","itcast.cn")
result.group() # 返回结果为 itcast
result = re.match("itcast","ITcast.cn",re.I)
result.group() # 返回结果为 ITcast
我们也可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配对象方法 | 描述 |
---|---|
group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() | 返回一个包含所有小组字符串的元组 |
# -*- coding: utf-8 -*-
import re
result = re.match("(\w+)\.(\w+)","itcast.cn")
ret1 = result.group()
print(ret1) # 返回 itcast.cn
ret2 = result.group(1)
print(ret2) # 返回 itcast
ret3 = result.group(2)
print(ret3) # 返回 cn
ret4 = result.group(1,2)
print(ret4) # 返回 ('itcast','cn')
ret5 = result.groups()
print(ret5) # 返回 ('itcast','cn')
匹配分组
字符 | 功能 |
---|---|
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P<name>) | 分组起别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
示例:匹配出 <html>hh</html>
import re
# 能够完成对正确的字符串的匹配
ret = re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>", "<html>hh</html>")
print(ret.group())
# 如果遇到非正常的html格式字符串,匹配出错
ret = re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>", "<html>hh</htmlbalabala>")
print(ret.group())
# 正确的理解思路:如果在第一对<>中是什么,按理说在后面的那对<>中就应该是什么
# 通过引用分组中匹配到的数据即可,但是要注意是元字符串,即类似 r""这种格式
ret = re.match(r"<([a-zA-Z]*)>\w*</\1>", "<html>hh</html>")
print(ret.group())
# 因为2对<>中的数据不一致,所以没有匹配出来
test_label = "<html>hh</htmlbalabala>"
ret = re.match(r"<([a-zA-Z]*)>\w*</\1>", test_label)
if ret:
print(ret.group())
else:
print("%s 这是一对不正确的标签" % test_label)
运行结果:
示例:匹配出<html><h1>www.itcast.cn</h1></html>
#coding=utf-8
import re
labels = ["<html><h1>www.itcast.cn</h1></html>", "<html><h1>www.itcast.cn</h2></html>"]
for label in labels:
ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", label)
if ret:
print("%s 是符合要求的标签" % ret.group())
else:
print("%s 不符合要求" % label)
运行结果:
示例:(?P<name>) 和 (?P=name)
#coding=utf-8
import re
ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")
ret.group()
re.compile 函数
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
语法格式:re.compile(pattern[, flags])
-
pattern : 一个字符串形式的正则表达式
-
flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
- re.I 忽略大小写
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
- re.M 多行模式
- re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
- re.X 为了增加可读性,忽略空格和 # 后面的注释
import re
pattern = re.compile(r'\d+')
string = 'one12twothree34four'
ret = pattern.match(string) # 无匹配结果
print(ret)
ret = pattern.match(string,3,10) # 从1的位置开始匹配,能匹配上
print(ret) # <re.Match object; span=(3, 5), match='12'>
print(ret.group()) # 返回 12
print(ret.start()) # 返回匹配到的起始位置索引:3
print(ret.end()) # 返回匹配到的结束位置索引:5
print(ret.span()) # 返回匹配的起始和结束位置索引
re模块的高级用法
re.search :扫描整个字符串并返回第一个成功的匹配
#coding=utf-8
import re
ret = re.search(r"\d+", "阅读次数为 9999")
ret.group() # 返回 9999
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
re.findall 扫描整个字符串并返回所有成功的匹配
#coding=utf-8
import re
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret) # 返回 ['9999', '7890', '12345']
re.sub 将匹配到的数据进行替换
语法:re.sub(pattern, repl, string, count=0, flags=0)
参数:
- pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
#coding=utf-8
import re
ret = re.sub(r"\d+", '998', "python = 997, cc=192, java=1000")
print(ret) # 返回 python = 998, cc=998, java=998
ret = re.sub(r"\d+", '998', "python = 997, cc=192, java=1000",2)
print(ret) # 返回 python = 998, cc=998, java=1000
def add(temp):
strNum = temp.group()
num = int(strNum) + 1
return str(num)
ret = re.sub(r"\d+", add, "python = 997, cc=192, java=1000")
print(ret) # 返回 python = 998, cc=193, java=1001
re.split 根据匹配进行切割字符串,并返回一个列表
#coding=utf-8
import re
# 根据 :和空格分割
ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret) # 返回 ['info', 'xiaoZhang', '33', 'shandong']
r的作用
Python中字符串前面加上 r 表示原生字符串,与大多数编程语言相同,正则表达式里使用 “\” 作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符 “\” ,那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。