1.数字和字母都表示它本身
2.很多字母前面添加 \ 会有特殊含义(重点学习)
3.绝大多数标点符号都有特殊的含义
4.如果想要使用标点符号,需要加 \
import re
re.search(r'x','hello xyz')
re.search(r'5','23r49534')
print(re.search(r'd', 'good')) # <re.Match object; span=(3, 4), match='d'> 字母d是普通的字符
print(re.search(r'\d', 'good')) # None \d 有特殊含义,不再表示字母d
print(re.search(r'\d', 'good4gfdghf')) # <re.Match object; span=(4, 5), match='4'>
# print(re.search('+', '1+2')) # 不能直接用, + 有特殊含义
print(re.search('\+', '1+2')) # <re.Match object; span=(1, 2), match='+'>
标点符号的含义
import re
# \s 表示任意的非打印字符(空白字符)
print(re.search(r'\s', 'hello world')) # <re.Match object; span=(5, 6), match=' '> 表示空格
print(re.search(r'\n', 'hello\nworld')) # <re.Match object; span=(5, 6), match='\n'> 表示换行
print(re.search(r'\t', 'hello\tworld')) # <re.Match object; span=(5, 6), match='\t'> 表示制表符
# \S 表示非空白符
print(re.search(r'\S', '\t\n x')) # <re.Match object; span=(5, 6), match='x'> 表示非空白符的所有字符
# 标点符号的使用:
# 1 () 用来表示一个分组
m = re.search(r'h(\d+)x','sh829xkflsa') # \d+ 表示数字
print(m) # <re.Match object; span=(1, 6), match='h829x'>
print(m.group(1)) # 829
m1 = re.search(r'\(.*\)','(1+1)*3+5') # 如果要表示括号要写 \
print(m1.group()) # (1+1)
# 2 . 表示匹配除了换行以为的任意字符.如果想要匹配 . 需要使用 \
甲 = '近日,硕士生毕业送外卖引发热议。当事人何成表示:很多人不理解我,我只是没找到合适的工作,并且需要养活自己。'
乙 = re.search('....',甲)
print(乙.group()) # 近日,硕
# 3 [] 表示可选项表示单个值 [x-y]从x到y区间,包含x和y
m2 = re.search(r'f[0-5]m','pdsf6m')
print(m2) # None
m3 = re.search(r'f[0-5]+m','pdsf06m')
print(m3) # None
m4 = re.search(r'f[a-d]+m','pdsfaacm')
print(m4) # <re.Match object; span=(3, 8), match='faacm'>
m5 = re.search(r'f[0-5a-dx]+z','adfaa110xxxz') # 0-5或a-d或x
print(m5) # <re.Match object; span=(2, 9), match='faa110xxxz'>
m6 = re.search(r'f[05adx]+z','adf000000z') # 或者0或者5或者a或者d或者x
print(m6) # <re.Match object; span=(2, 10), match='f000000z'>
# 4 | 表示或者 和[]有一定的相似,但是有区别 []里的值表示区间而且是单个字符, | 就是可选值可以出现多个值
print(re.search(r'f(x|prz|t)m', 'pdsfprzm')) # <re.Match object; span=(3, 8), match='fprzm'>
# 5 {} 表示限定前面字符出现的次数
# {n} 表示前面单个元素出现n次,如果是god或goood就匹配不上了
print(re.search(r'go{2}d', 'good')) # <re.Match object; span=(0, 4), match='good'>
# {n,} 表示前面元素出现n次以上,包括2次
print(re.search(r'go{2,}d', 'good')) # <re.Match object; span=(0, 4), match='good'>
# {,n} 表示前面元素出现n次以下,包括2次
print(re.search(r'go{,2}d', 'gd')) # <re.Match object; span=(0, 2), match='gd'>
# {m,n} 表示前面元素出现m到n次,包括m和n
print(re.search(r'go{3,5}d', 'goooood')) # <re.Match object; span=(0, 7), match='goooood'>
# 6 * 表示前面元素出现任意次数(0次及以上,等价于{0,})
print(re.search(r'go*d', 'goooooooooooooooooood')) # <re.Match object; span=(0, 21), match='goooooooooooooooooood'>
# 7 + 表示前面的元素出现1次及以上,等价于{1,}
print(re.search(r'go+d', 'goooood')) # <re.Match object; span=(0, 7), match='goooood'>
# 8 ? 两种用法
# 1):规定前面的元素出现1次及以下,等价于{,1}
# 2):将贪婪模式转换成为非贪婪模式
print(re.search(r'go?d', 'god')) # None
# 9 ^ 表示以指定内容开头 $ 表示指定内容结尾
print(re.search(r'^a.*i$', 'sd aofidf')) # None 只能匹配整个字段串是以a开头和i结尾
# ^除了表示内容开始外,还可以在[^0-9]里使用表示取反
print(re.search(r'[^9]+', '98888')) # <re.Match object; span=(1, 5), match='8888'>
字母的特俗含义
# 字母表示它本身,很多字母前面加\ 会有特殊含义
# \n 表示换行 \t 表示制表符 \s 表示空白字符 \S非空白字符
# \d 表示一个数字,等价于[0-9]
import re
print(re.search(r'x\dp', 'x243p')) # None 因为\d表示一个数字,所以不匹配哦
print(re.search(r'x[0-9]+p', 'x243p')) # <re.Match object; span=(0, 5), match='x243p'>
# \D 表示非数字,等价于[^0-9]
print(re.search(r'\D+', 'he110')) # <re.Match object; span=(0, 2), match='he'>
print(re.search(r'[^0-9]+', 'he110')) # <re.Match object; span=(0, 2), match='he'>
# \w 表示数字 字母 中文以及_ 非标点符号
print(re.findall(r'\w+', 'h+E-11.0_x*.+-')) # ['h', 'E', '11', '0_x']
print(re.findall(r'\w+', '大家好+,今天天气很好呀!')) # ['大家好', '今天天气很好呀']
# \W 取反
print(re.findall(r'\W', 'h+E-11.0_x*.+-')) # ['+', '-', '.', '*', '.', '+', '-']
正则替换
# 正则表达式作用是用来字符串检索和替换
# 检索: match search fullmatch finditer findall
# 替换: sub 第一个参数:正则表达式 第二个参数:新字符或变量或一个函数 第三个参数:需要被替换的字符串
import re
t = 'afo2dlkf23af245qou3095'
# 把匹配到到\d(即数字)替换成x
print(re.sub(r'\d', 'x', t)) # afoxdlkfxxafxxxqouxxxx
print(re.sub(r'\d+', 'x', t)) # afoxdlkfxafxqoux 如果加了+会把23和245以及3095作为一个字符替换成x
def test(x):
y = int(x.group())
y *= 2
return str(y)
print(re.sub(r'\d+', test, t)) # afo4dlkf46af490qou6190 这里要使用\d+ 否则会把245当成三个字符来取 经过函数处理就是4810
贪婪模式和非贪婪模式
# 在python的正则表达式里默认是贪婪模式,尽可能多的匹配
# 在贪婪模式后面添加 ? 可以转换成非贪婪模式,尽可能少的匹配
import re
m = re.search(r'm.*a','o3rjomjadas') # 默认是贪婪模式
print(m.group()) # mjada
# 只要是正则式时区范围区间的都可以转换成非贪婪模式
# 1 .*? 非换行的任何字符任意次数
n = re.search(r'm.*?a','o3rjomjadas') # 在.*后面加?即转换成非贪婪模式
print(n.group()) # mja
# 2 \d+? 匹配任意数字任意次数
甲 = re.search(r'aa(\d+?)', 'aa2343ddd')
print(甲.group()) # aa2
print(甲.group(1)) # 2
甲1 = re.search(r'aa(\d+?ddd)', 'aa2343ddd') # 这种情况没法贪婪了.因为要满足匹配条件
print(甲1.group()) # aa2343ddd
print(甲1.group(1)) # 2343ddd
甲2 = re.search(r'aa(\d+?).*','aa2343ddd') # 可以只非贪婪一个分组
print(甲2.group()) # aa2343ddd
print(甲2.group(1)) # 2
甲3 = re.search(r'aa(\d??)(.*)','aa2343ddd') # 非贪婪第一个分组,都给后面的.*
print(甲3.group(0)) # aa2343ddd
print(甲3.group(1)) # 空
print(甲3.group(2)) # 2343ddd
# 3 \d{2,}?
乙 = re.search(r'aa(\d{2,}?)', 'aa2343ddd')
print(乙.group(0)) # aa23
print(乙.group(1)) # 23
# 使用场景: 取主网址不要后面参数-->https://image.baidu.com
src = 'https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E4%B8%AD%E6%96%87%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80&step_word=&hs=0&pn=0&spn=0&di=7117150749552803841&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=2951359401%2C3343582152&os=2143431253%2C4278410788&simid=2951359401%2C3343582152&adpicid=0&lpn=0&ln=1531&fr=&fmq=1663483752298_R&fm=&ic=undefined&s=undefined&hd=undefined&latest=undefined©right=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=https%3A%2F%2Fgimg2.baidu.com%2Fimage_search%2Fsrc%3Dhttp%3A%2F%2Fpic2.zhimg.com%2Fv2-b1a4a4f5bce89c86067f40daeaa299ef_1440w.jpg%3Fsource%3D172ae18b%26refer%3Dhttp%3A%2F%2Fpic2.zhimg.com%26app%3D2002%26size%3Df9999%2C10000%26q%3Da80%26n%3D0%26g%3D0n%26fmt%3Dauto%3Fsec%3D1666075756%26t%3D270603f1cb3195d4776e8e8fff98bf5c&fromurl=ippr_z2C%24qAzdH3FAzdH3Fzi7wgswg_z%26e3Bziti7_z%26e3Bv54AzdH3FrAzdH3Fnnlnmlnam&gsm=1&rpstart=0&rpnum=0&islist=&querylist=&nojc=undefined&dyTabStr=MCwxLDUsMywyLDQsNiw4LDcsOQ%3D%3D'
丙 = re.search(r'https://.*?\.com',src)
print(丙.group()) # https://image.baidu.com