re模块

re模块

re引擎由c编写

.元字符

一个.代表匹配一个任意字符(除了 ),下面代码表示2个字符在中间

import re
lis="gdnm tfnb xzxxlxxlzxzzcassfagkffdkgfkdkgkwsiil"
zx=re.findall("l..l",lis)
print(zx)

['lxxl']

^元字符

字符开头为标准,只匹配开头,如代码,当str开头为l满足^的条件,然后继续匹配其他条件

import re
lis="gdnm tfnb xzxxlxxlzxzzcassfagkffdkgfkdkgkwsiil"
lis="lgdlnm tfnb xzxxlxxlzxzzcassfagkffdkgfkdkgkwsiil"
zx=re.findall("^l..l",lis)
zx=re.findall("^l..l",lis)
print(zx)

['lgdl']

贪婪匹配:有多少匹配多少

$元字符

$匹配文本结束

*元字符

前一个字母的重复数量,0到无穷

+元字符

前一个字母的重复数量,1到无穷

import re
lis="asdfghjk"
lis2="asdfghjk"
zx=re.findall("jkl*",lis)
zx2=re.findall("jkl+",lis)
print(f"zx:{zx}")
print(f"zx2:{zx2}")

zx:['jk']
zx2:[]

因为+至少要有一个l,所以没找到,而*的话可以有0个l,所以匹配到了jk

?元字符

?的范围是0到1次

{}元字符

自定义范围

{0,+00}==*
{1,+00}==+
{0,1}==?
{6}==6
{0,}==*

惰性匹配

在元字符后面加上问号?即可,然后就会默认取最小的重复

import re
lis="asdfghjkkkkk"
zx=re.findall("jk*?",lis)
zx2=re.findall("jk+?",lis)
zx3=re.findall("jk{3}?",lis)
print(f"zx*?:{zx}")
print(f"zx+?:{zx2}")
print(f"zx{3}?:{zx3}")

zx*?:['j']
zx+?:['jk']
zx3?:['jkkk']

*最小为0所以没有k,+最小为1所以有一个k,而{3}只有3,最小就为3所以取3个k

[]元字符(字符集)

在[]里面只支持,-,^,其他符号视为字符

[]只取一个值,除非加了其他的元字符

import re
lis="asdjh546fghjkkkkkakkk"
zx=re.findall("a[a-z]",lis)
zx2=re.findall("a[a-z]*",lis)
zx3=re.findall("a[a-z]{2}",lis)
print(f"zx:{zx}")
print(f"zx2:{zx2}")
print(f"zx3:{zx3}")

zx:['as', 'ak']
zx2:['asdjh', 'akkk']
zx3:['asd', 'akk']

^符号在[]

^在[]中并不是,取首字符的意思,而是非的意思

import re
lis="asdjh546fghjka643kkkkakkk"
zx=re.findall("a[^a-z]",lis)
print(f"zx:{zx}")

zx:['a6']

元字符之转义符

re转义

举两个例子

import re
zx=re.findall('\\d',"jbsvu9||d")
print(zx)
print(len(zx[0]))
print('d')
print('\d')

['d']
2
d
d

首先d在python是没有意义的,这行代码在pycharm中首先被转义成\d,然后给re引擎,re引擎在转义成d,最终可以匹配到字符串中的d,虽然拿到的是\d,因为又被转义了

import re
zx=re.findall('\\f',"jbsvu9||\f")
print(zx)
print(len(zx[0]))
print('f')
print('\f')

['f']
2
这里是个符号....这里无法显示
f

f在python中有意义

|元字符

相当于或

import re
zx='k|kdlk|a'
print(re.findall('k|a',zx))

['k', 'k', 'k', 'a']

分组(search)

分组格式(?P条件)

search只匹配第一个

import re
ll="zx100 sadk2 asjk12 asd12 zx323 zx23 damsl12"
r=re.search("(?P<name>[a-z]+)d+",ll)
print(r)
print(r.group('name'))

<_sre.SRE_Match object; span=(0, 2), match='zx100'> 可以看到匹配的位置和字符

zx

那么怎么分两个组呢?

import re
ll="zx100 sadk2 asjk12 asd12 zx323 zx23 damsl12"
r=re.search("(?P<name>[a-z]+)(?P<age>d+)",ll)
print(r)
print(r.group('name'))
print(r.group('age'))

()

把()里的看做一个整体,比如一个字母a

import re
l1="abcabcabcabcabcabclsd"
print(re.findall("(abc)+",l1))
print(re.findall("(?:abc)+",l1))

['abc']
['abcabcabcabcabcabc']

为啥会变成1这种情况,可以理解为括号的优先级高,会优先打印这个字符,所以通过?:去优先级

match

类似加了^的search,从头开始匹配第一个

import re
l1="45sdf1"
l2="sdfnj43"
print(re.match('d+',l1))
print(re.match('d+',l2))

<_sre.SRE_Match object; span=(0, 2), match='45'>
None

splite

re自己的splite与 python的有啥区别呢?

re的splite能用正则!

但是有坑

import re
l1="dakh jad sda|sad"
l2=" |das|dsa"
print(re.split('[ |]',l1))
print(re.split('[ |]',l2))

['dakh', 'jad', 'sda', 'sad']
['', '', 'das', 'dsa']

第一种结果很好理解

第二种为啥这样,说下流程
首先去字符串找“ “找到了,然后左边没有内容,于是他把字符分成两块,然后继续找,找到了|这个字符,然后这字符左边也是空,所以也把他分成了两块

sub

re的替换,第4个参数是替换的个数

import re
l1="zx213jlds534"
print(re.sub("d","A",l1))
print(re.sub("d","A",l1,3))

compile

import re
l1="fgk983nfd984"
com=re.compile("d")
print(com.findall(l1))

相当于配置了匹配规则的re对象,可以提高编码效率

finditer

import re

l1="397053ubds9u2hrbfh98"

print(re.finditer("d",l1))

<callable_iterator object at 0x000001D048001FD0>
返回一个迭代器对象,有啥好处呢,当数据很大的时候,可以使用迭代器拿数据一个一个取,但是迭代出来的还是对象,需要.grounp取值

finall实验

import re
l1="www.5463.com"
print(re.findall("www.(5463).com",l1))

['5463']

会优先去找()里的

import re
l1="www.5463.com"
print(re.findall("www.(?:5463).com",l1))

['www.5463.com']

加上?:可以去优先级

原文地址:https://www.cnblogs.com/zx125/p/11402660.html