正则表达式是什么
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式使用单个字符串pattern来描述、匹配一系列符合某个句法规则的字符串string。
七个例子
举例一 写什么就匹配什么
text = '2022114292,你是:Nxb, 体重:168, 学号:2022114292, 密码:131456,生日:1999-03-02, 座机号码是+86-15893860196'
print(re.findall(r'131456',text))
#['131456']
r:表示raw-原始字符,告诉编译器后面文本中的反斜杠不用转义。
re.findall(pattern,text,flags) 模式 字符串,附加条件。返回匹配列表。
举例二 找出特定的数字、字母。
print(re.findall(r'\d',text))
#['2', '0', '2', '2', '1', '1', '4', '2', '9', '2', '1', '1', '6', '8', '2', '0', '2', '2', '1', '1', '4', '2', '9', '2', '1', '3', '1', '4', '5', '6', '1', '9', '9', '9', '0', '3', '0', '2', '8', '6', '1', '5', '8', '9', '3', '8', '6', '0', '1', '9', '6']
print(re.findall(r'[a-z]', text))
#['x', 'b']
一些元字符
字符类别
a,b,c,d,1,2,3 字符常量写什么是什么
\d 单个的数字。\D 除了数字以外的任何字符。
\w 任意字母或数字下划线 。\W 除了任意字母或数字下划线
\s 一个空格。\S 一个非空格
[abcd] abcd中任意一个字符
[a-g] 范围:a~g的小写字母
[^a-g] 取反:除了a~g以外的任意字符
[\b] 退格符号
. 统配符,除了换行符\n之外任何一个字符
重复次数-量词
* 0或多个
+ 1或多个
? 0或1个
{2} 2个
{2,5} 2到5个
{2,} 至少2个
{,5} 最多5个
.* 贪婪匹配 尽可能多。aabab #aabab
.*? 懒惰匹配 尽可能少 aabab #aab
text = 'aabab'
print(re.findall(r'a.*?b',text))
print(re.findall(r'a.*b', text))
#['aab', 'ab']
#['aabab']
举例三 找出连续的数字
print(re.findall(r'\d+',text))
#['2022114292', '168', '2022114292', '131456', '1999', '03', '02', '86', '15893860196']
print(re.findall(r'\d{3}', text))
#['202', '211', '429', '168', '202', '211', '429', '131', '456', '199', '158', '938', '601']
\d+中的’+‘修饰’\d’,表示1~n个数字。
\d{3} 表示连续3个数字为匹配模式
\d{3,4} 3个或4个连续数字为模式
举例四 找出文本中的座机号码
text = '手机号:18430792543,你是:Nxb, 体重:168, 学号:2022114292, 密码:131456,生日:1999-03-02, 座机号码是010-86551122'
print(re.findall(r'\d{2,3}-\d{8}', text))
#['010-86551122']
举例五 找出文本中的手机号或者座机号码
print(re.findall(r'\d{9}|\+\d{2,3}-\d{8}',text))
#['184307925', '202211429', '010-86551122']
用’|‘表示或,从左往右先匹配’|'前面的模式,不满足再匹配后面的模式
匹配模式中不能有空格
举例六 限定了位置 要求出现在句子开头的学号或手机号码
text = '18430792543,你是:Nxb, 体重:168, 学号:2022114292, 密码:131456,生日:1999-03-02, 座机号码是010-86551122'
print(re.findall(r'^\d{9}|\d{2,3}-\d{8}$',text))
#['184307925', '010-86551122']
位置匹配
^ 匹配一个行首或字符串的开头的位置
$ 匹配一个行末或字符串结束的位置
\b 匹配一个单词的边界 \B 匹配一个非单词边界
举例七
分组
组合模式 两种或以上的简单模式组合在一起,拼接、二选一
\d{6}[a-g]{6} 连续6个数字后面跟6个连续的a~g的字母
() 分为一组作为单独的量词
(abc){3} 表示 abcabcabc
text1 = 'barbar,dardar,bardar''
print(re.findall(r'(\w{3})(\1)',text1))
#[('bar', 'bar'), ('dar', 'dar')]
\w{3}表示任意三个连续字符,\1表示后续的三个连续字符和第一个()分组内的(\w{3})所得的字符串一样
python的正则表达式引擎——re的用法
re有八个方法
一、查找
re.search() 只返回一个Match对象
re.match() 只返回一个Match对象,从头个字符开始匹配
re.finditer() 返回Match迭代器
以上三个匹配不到时,返回None
re.findall() 返回字符串列表
看例子
text2 = '电话簿,张三:0866 15893860196,李四:086 19147838506'
m = re.search(r'(\d{3,4}) (\d{11})', text2)
print(m)
#<re.Match object; span=(7, 23), match='0866 15893860196'>
print(m.group)
#0866 15893860196
print(m.group(2))
#15893860196
python中的match对象是一次匹配的结果,其包含了很多匹配的相关信息<...>
match对象只包含的是一次匹配的结果,只返回第一次匹配的结果.
match对象涉及的相关方法
.group() : 获得匹配后的字符串。如果已经分组,.group(1)返回第1个分组,.group(2)返回第2个,.group()返回所有分组
.start() : 匹配字符串在给定字符串的开始位置下标
.end() : 匹配字符串在给定字符串的结束位置下标
.span() : 返回一个元组类型,包含开始位置下标和结束位置下标
如果需要得到每一次返回的match对象,可以由finditer()方法进行迭代来获取。
text2 = '电话簿,张三:0866 15893860196,李四:086 19147838506'
m = re.finditer(r'\d{3,4} \d{11}', text2)
print(m)
#<callable_iterator object at 0x00000183B0835910>
for i in m:
print(i.group())
#0376 15893860196
#086 19147838506
flags
flags = re.I
忽略字母大小写 ignore case
flags = re.M
multi line 多行
使用本标志后,‘^’和‘$’匹配行首和行尾时,会增加换行符之前和之后的位置。
flags = re.S
dot matches all
使 “.” 特殊字符完全匹配任何字符,包括换行\n
text2 = 'abc,Abc,ABC'
print(re.findall(r'abc',text2,flags=re.I))
#['abc', 'Abc', 'ABC']
二、替换
re.sub(pattern, repl, string, count, flags)
在string里将pattern替换成repl,count表示是要替换的最大次数(0是所有),count和flags可以不写。返回替换后的字符串,不会修改原字符串。
re.subn() 返回替换完的字符串 和 替换了几次
text3 = '$$x^2 + y^2 = z$$ $ $ $ $'
print(re.sub(r'\$', '',text3))
#x^2 + y^2 = z
print(re.subn(r'\s','',re.sub(r'\$', '',text3)))
#('x^2+y^2=z', 10)
print(text3)
#$$x^2 + y^2 = z$$ $ $ $ $
三、分割
re.split(pattern, string, maxsplit=0, flags=0)
用pattern将字符串string分割,maxsplit:分割的最大次数。
text4 = ".大家好, 我是一个程序员小白 。 I'm so glad to introduce myself, and I’m 18 years old."
print(re.split(r'\s*[,。,.]\s*',text4))
#['', '大家好', '我是一个程序员小白', "I'm so glad to introduce myself", 'and I’m 18 years old', '']
四、打包
re.compile(pattern,flags=0)
此函数用于编译正则表达式,生成一个 Pattern对象
text5 = '123456789'
p = re.compile(r'\d{3}')
print(re.findall(p,text5))
#['123', '456', '789']
一些工具
测试正则表达式的网站
https://deerchao.cn/tools/wegester/