# 正则表达式 —练习实践
import re
pattrn = "abc"
str1 = "qwe"
result = re.match(pattrn,str1)
print(result) # 匹配不到,返回默认值 None
# str1为匹配的对象,match为从头匹配,pattrn为匹配规则
str2 = "abc"
result1 = re.match(str2,pattrn)
print(result1) # <_sre.SRE_Match object; span=(0, 3), match='abc'>
print(result1.group())# abc 打印匹配的数据
"""
1、单字符匹配
. 匹配任意一个字符,除了 /n ,如果加上 re.
[] 匹配[] 中列举的字符
\d 匹配数字 0-9
\D 匹配非数字
\s 匹配空白,即空白,Tab,\n,\t
\S 匹配非空白
\w 匹配单词字符,a-z,A-Z,0-9,_ 共63个字符,包括各国文字
\W 匹配非单词字符
注: 这些字符只匹配一个字符
"""
import re
ret = re.match(r".","a")
print(ret)
print(ret.group()) # a
ret = re.match(r"..","abc")
print(ret) # <_sre.SRE_Match object; span=(0, 2), match='ab'>
print(ret.group()) # ab
# 注意: 一个 . 只能匹配一个字符。并且匹配的规则的数量一定要比 匹配字符串的数量要多
ret = re.match(r"..","a")
print(ret) # None
print("1"*20)
"""
\d 匹配数字
\D 匹配非数字
"""
ret = re.match("\d","123")
print(ret) # 1
ret = re.match("\D", "abc")
print(ret) # a
print("2"*20)
"""
\s 匹配空白,eg: Tab,空字符串,空格,\n,\t,\n\t.
\S 匹配非空白
"""
ret =re.match(r"\s","")
print(ret)
ret = re.match(r"\s","\n")
print(ret)
ret = re.match(r"\s","\t")
print(ret)
ret = re.match(r"\s","\n\t")
print(ret)
ret = re.match(r"\s"," ") # 匹配Tab键
print(ret)
ret = re.match(r"\S","abc")
print(ret) # a
"""
打印结果
None
<_sre.SRE_Match object; span=(0, 1), match='\n'>
<_sre.SRE_Match object; span=(0, 1), match='\t'>
<_sre.SRE_Match object; span=(0, 1), match='\n'>
<_sre.SRE_Match object; span=(0, 1), match=' '>
<_sre.SRE_Match object; span=(0, 1), match='a'>
"""
print("3"*20)
"""
\w 匹配单词字符,a-z,A-Z,0-9,_ 63个字符串,还包含各国文字[\u4e00-\u9fa5] 表示所有的中文
\W 匹配非单词字符
"""
ret = re.match(r"\w","abc")
print(ret)
ret = re.match(r"\w+","Ac232_")
print(ret)
ret = re.match(r"\w+","中国")
print(ret)
ret = re.match(r"\W","#")
print(ret)
ret = re.match(r"\W","¥")
print(ret)
"""
打印结果:
<_sre.SRE_Match object; span=(0, 1), match='a'>
<_sre.SRE_Match object; span=(0, 6), match='Ac232_'>
<_sre.SRE_Match object; span=(0, 2), match='中国'>
<_sre.SRE_Match object; span=(0, 1), match='#'>
<_sre.SRE_Match object; span=(0, 1), match='¥'>
"""
print("4"*20)
# 原始字符串
import re
s = "c\\b\\a"
print(s) # c\b\a
ret = re.match(r"c\\b\\a","c\\b\\a")
print(ret)
ret = re.match(r"a.","ab")
print(ret) # 这里面的 . 不是普通字符
ret = re.match(r"a\.b","acb")
print(ret) # 这里面的 . 是普通字符,没有其他的含义
ret = re.match(r"a.b","acb")
print(ret) # 这里面的 . 是普通字符,没有其他的含义
ret = re.match(r"a\.b","a.b")
print(ret)
ret = re.match(r"[a,h,j,s]","abc")
print(ret)
ret = re.match(r"\[a\]","[a]")
print(ret)
# 注 : 加上 \ 表示反转义,使原来的字符没有特殊的含义。
"""
打印结果:
c\b\a
<_sre.SRE_Match object; span=(0, 5), match='c\\b\\a'>
<_sre.SRE_Match object; span=(0, 2), match='ab'>
None
<_sre.SRE_Match object; span=(0, 3), match='acb'>
<_sre.SRE_Match object; span=(0, 3), match='a.b'>
<_sre.SRE_Match object; span=(0, 1), match='a'>
<_sre.SRE_Match object; span=(0, 3), match='[a]'>
"""
print("5"*20)
"""
3、 表示数量的正则:
* 匹配前一个字符出现0次或者多次
+ 至少出现一次
? 匹配前一个字符0次或者1次
{m} 匹配前一个字符出现 m 次
{m,n} 匹配前一个字符出现m到n次,至少m次
{m,} 匹配前一个字符至少出现m次
"""
import re
ret = re.match(r"abc{2,4}","abccccccccc")
print(ret)
ret = re.match(r"abc{2,}","abccccccccc")
print(ret)
ret = re.match(r"abc{2}","abccccccccc")
print(ret)
ret = re.match(r"abc+","abcccccccccccc")
print(ret)
ret = re.match(r"abc*","abcc")
print(ret)
ret = re.match(r"abc*","ab")
print(ret)
"""
打印结果:
<_sre.SRE_Match object; span=(0, 6), match='abcccc'>
<_sre.SRE_Match object; span=(0, 11), match='abccccccccc'>
<_sre.SRE_Match object; span=(0, 4), match='abcc'>
<_sre.SRE_Match object; span=(0, 14), match='abcccccccccccc'>
<_sre.SRE_Match object; span=(0, 4), match='abcc'>
<_sre.SRE_Match object; span=(0, 2), match='ab'>
"""
print("6"*20)
"""
4 、表示边界
^ 匹配字符串的开头
$ 匹配字符串的结尾
\b 匹配一个单词的边界,
\B 匹配非单词边界,
"""
import re
ret = re.search(r"world","hello world")
print(ret)
ret = re.search(r"^world","hello world")
print(ret)
ret = re.search(r"world$","hello world")
print(ret)
ret = re.search(r"who\b","who am i")
print(ret)
ret =re.search(r"who\b am","who am")
print(ret)
"""
打印结果:
<_sre.SRE_Match object; span=(6, 11), match='world'>
None
<_sre.SRE_Match object; span=(6, 11), match='world'>
<_sre.SRE_Match object; span=(0, 3), match='who'>
<_sre.SRE_Match object; span=(0, 6), match='who am'>
"""
print("6"*20)
"""
6、 匹配分组:
| 匹配左右两边任意的表达式
(ab) 将括号
\num 引用分组num匹配的字符串
(?P<name>) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串
"""
import re
ret = re.match(r"[1-7]?\d|100","70") # [1-9] 表示 1-9 中任意的数字
print(ret)
ret = re.match(r"[1-9]?\d|70","7")
print(ret)
ret = re.match(r"[0-9]?\d$|100","07")
print(ret)
s="<html><h1>itcast</h1></html>"
ret = re.match(r"<(.+)><(.+)>.+</\2></\1>",s) #\num 的作用
print(ret)
print(ret.groups()) # 表示匹配到的组数 ("html","h1")
print(ret.group()) # 表示匹配的全部内容 <html><h1>itcast</h1></html>
print(ret.group(0)) # 表示匹配的全部内容 <html><h1>itcast</h1></html>
print(ret.group(1)) # 表示匹配到的第一个小括号的内容
print(ret.group(2)) # 表示匹配到的第二个小括号的内容
print("*"*20)
s="<html><h1>itcast,1</h1></html>"
ret =re.match(r"<html><h1>(.+),1</h1></html>",s)
print(ret)
print(ret.group(1))
# (?P<name>) 起别名 (?P=name) 引用别名
s = "<html><b>itcast</b></html>"
ret = re.match(r"<(?P<g1>.+)><(?P<g2>.+)>.+</(?P=g2)></(?P=g1)>",s)
print(ret)
print(ret.group())
"""
打印结果:
<_sre.SRE_Match object; span=(0, 2), match='70'>
<_sre.SRE_Match object; span=(0, 1), match='7'>
<_sre.SRE_Match object; span=(0, 2), match='07'>
<_sre.SRE_Match object; span=(0, 28), match='<html><h1>itcast</h1></html>'>
<html><h1>itcast</h1></html>
<html><h1>itcast</h1></html>
html
h1
********************
<_sre.SRE_Match object; span=(0, 30), match='<html><h1>itcast,1</h1></html>'>
itcast
<_sre.SRE_Match object; span=(0, 26), match='<html><b>itcast</b></html>'>
<html><b>itcast</b></html>
"""
"""
注 : [^0-9] 表示除了 0-9之外的字符 ^ 在内部使用的时候 表示相反的意思。
"""
"""
6、 正则表达式的函数
re模块的高级用法:
compile 函数 : 用于编译正则表达式,生成一个Pattern 对象
格式:
import re
pattern = re.compile(正则表达式)
比如说:
parrern =re.compile(r"\d+")
Pattern 对象的一些常用方法主要有:
match () : 从起始位置开始查找,一次匹配
search() : 从任意位置开始查找,一次匹配
findall() : 全部匹配,返回一个列表
finditer(): 全部匹配,返回迭代器
split() : 分割字符串,返回一个列表
sub() : 替换字符串
"""
"""
match() 函数 match(string,[start,end])
含义:
start : 这个值可以取到 这里面是索引为 16 的字符
end : 这个值取不到 这里面是索引为 23 的字符
跟列表的切片一样,前闭后开 [ start, end )
"""
print("7"*20)
import re
info = "abc"
pattern = re.compile(r"\w+")
ret = pattern.match(info)
print(ret)
info = "http://www.taobaooo.com"
pattern = re.compile(r"o+\.com")
ret = pattern.match(info,16,23)
print(ret)
print(ret.group()) # ooo.com
print(ret.span()) # (16,23)
print(ret.start()) # 16
print(ret.end()) # 23
"""
打印结果:
77777777777777777777
<_sre.SRE_Match object; span=(0, 3), match='abc'>
<_sre.SRE_Match object; span=(16, 23), match='ooo.com'>
ooo.com
(16, 23)
16
23
"""
"""
search() 函数
search(string,[start,end])
re.I 忽略大小写
re.M 只影响 ^ 和 $ , 多行匹配
当匹配到一个后,不会继续向下面匹配
"""
print("8"*20)
pattern = re.compile(r"\d+")
ret = pattern.search("one123two456")
print(ret)
pattern = re.compile(r"[a-z]+",re.I) # 忽略大小写
ret = pattern.search("ABcde3456")
print(ret)
pattern = re.compile(r"a$")
ret = pattern.search("dff\na")
print(ret)
"""
打印结果:
88888888888888888888
<_sre.SRE_Match object; span=(3, 6), match='123'>
<_sre.SRE_Match object; span=(0, 5), match='ABcde'>
<_sre.SRE_Match object; span=(4, 5), match='a'>
"""
"""
findall(string[,pos[,endpos]])
string 是匹配的字符串,后面是可选参数,指定字符串的起始和终点位置,默认值分别为0 和 字符串的长度
findall 以列表形式返回全部能匹配的子串,如果没有匹配,那么返回一个空的列表
"""
print("9"*20)
pattern = re.compile("a$",re.M)
ret = pattern.findall("a\naba")
print(ret)
pattern = re.compile("a$")
ret = pattern.findall("a\naba")
print(ret)
"""
打印结果:
99999999999999999999
['a', 'a']
['a']
"""
"""
finditer()
方法的行为跟 findall()的行为类似,也是搜索整个字符串
获得所有匹配的结果,但它返回的是一个迭代器对象。要遍历循环出来
"""
print("0"*20)
pattern = re.compile(r"[a-z]+",re.I)
ret = pattern.finditer("aBc123Acd/*")
print(ret)
for i in ret :
print(i)
print(i.group())
"""
打印结果:
00000000000000000000
<callable_iterator object at 0x0000021E169BA208>
<_sre.SRE_Match object; span=(0, 3), match='aBc'>
aBc
<_sre.SRE_Match object; span=(6, 9), match='Acd'>
Acd
"""
"""
split(string[,maxsplit])
maxsplit 用于指定最大的分割次数,不指定将符合要求的全部分割
"""
print("@"*20)
pattern = re.compile(r",")
ret = pattern.split("a,b,c,d,e")
print(ret)
ret2 = pattern.split("a,b,c,d,e",3)
# 这里面的分割次数为3,分割次数可以无限大,还是把所有符合的都分割
print(ret2)
ret2 = pattern.split("a,b,c,d,e",30)
# 这里面的分割次数为3,分割次数可以无限大,还是把所有符合的都分割
print(ret2)
"""
打印结果:
@@@@@@@@@@@@@@@@@@@@
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd,e']
['a', 'b', 'c', 'd', 'e']
"""
"""
sub(repl,string[,count])
这个不是从头匹配
其中 repl 可以是字符串,也可以是一个函数:
如果 repl 是字符串,则会使用repl去替换掉,并返回替换后的字符串,还可以使用id引用分组,但不能使用编号0
如果 repl 是函数,这个方法应当只接受一个参数 Match对象。并且返回一个字符串用于替换
count 用于指定最多替换次数,不指定时全部替换
"""
print("&"*20)
info = "a hello 123,hello haha"
ret = re.sub(r"hello","hi",info) # 默认全部替换
print(ret)
info = "a hello 123,hello haha"
ret = re.sub(r"hello","hi",info,1) # 替换1个
print(ret)
info = "hello 123, hello haha "
ret = re.sub(r"(\w+) (\w+)",r"\2\1",info)
print(ret)
print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
def add(x):
print(x)
print(type(x.group()))
return str(int(x.group())+1)
ret = re.sub(r"\d+",add,"python = 996 java = 100")
print(ret)
# 改写成匿名函数
ret = re.sub(r"\d+",lambda x : str(int(x.group())+1),"python = 10 java = 20")
print(ret)
"""
打印结果:
&&&&&&&&&&&&&&&&&&&&
a hi 123,hi haha
a hi 123,hello haha
123hello, hahahello
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
<_sre.SRE_Match object; span=(9, 12), match='996'>
<class 'str'>
<_sre.SRE_Match object; span=(20, 23), match='100'>
<class 'str'>
python = 997 java = 101
python = 11 java = 21
"""
"""
贪婪模式 和 非贪婪模式
贪婪模式 : 尽可能多的匹配自己可以接受的内容
非贪婪模式 : 前面正则可以匹配的,后面的正则也可以匹配的,让后面的正则来匹配
"""
print("%"*20)
info = '<img src="hahajpg"> style="display:inline"'
ret = re.findall(r'src="(.*)"',info)
print(ret)
info = '<img src="hahajpg"> style="display:inline"'
ret = re.findall(r'src="(.*?)"',info)
print(ret)
"""
打印结果:
%%%%%%%%%%%%%%%%%%%%
['hahajpg"> style="display:inline']
['hahajpg']
"""
re 模块的几个参数:
re.M 多行匹配, 影响 ^, $
re.S . 可以匹配任何字符,包括 \n
re.A 表示匹配 Ascii 码
re.U 都使用 unicode编码
re.I 忽略大小写