17 正则表达式、元字符
正则表达式
强烈建议!更全面的请查看:https://www.runoob.com/regexp/regexp-syntax.html
1.re标准库
re标准库是专门用来出来正则表达式的一个库。
import re
2.findall方法
a = 'C0C++44fjdsf*%$python##!jacaSCript'
# r = re.findall('正则表达式',字符串) 返回一个列表 正则表达式必须用引号引起来
r = re.findall('python',a) #从字符串a中找到所有的python
3.flags——模式
在findall、sub等方法都有一个flags参数,它表示模式,默认值为0。
主要的模式有:
- re.I 忽略大小写
- re.S 去除 . 的除换行符\n的功能让它能匹配所有字符
使用多个模式可用|来分割。
4.正则表达式
正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。
元字符使正则表达式具有处理能力。
所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
元字符大全:https://www.runoob.com/python/python-reg-expressions.html
5.re.sub替换方法
-
# 第一个参数:需要查找的正则表达式
-
# 第二个参数:需要替换成的字符串,重要:可以用函数来代替,用函数替换时会给这个函数传入查找到的字符串
-
# 第三个参数:count=0,表示查找并替换的次数
-
# 第四个参数:flags,表示模式
第二个参数用函数代替:
s1 = 'abc111abc2222' def convert(value): matched = value.group() return 'zzz'+matched+'!' r = re.sub('abc',convert,s1,1) 结果: zzzabc!111abc2222
举个例子
将字符串‘fd1234fds63249fdsgfs732hf’中所有大于等于6的数字改为9,小于6的改为0
s2 = 'fd1234fds63249fdsgfs732hf' def convert(value): matched = value.group() if int(matched) >= 6: return '9' else: return '0' #注意,返回的是字符而不是数字 r = re.sub('\d',convert,s2) print(r) 结果: fd0000fds90009fdsgfs900hf
6.match方法
re.match方法,从字符串的第一个字符开始匹配,如果第一个字符就不符合则停止匹配。如符合正则表达式也只匹配一个结果。返回值为对象。
7.search方法
re.search方法,从字符串的第一个字符开始寻找整个字符串,若找到一个结果,则停止寻找,返回值为对象。
8.group与groups方法
从search方法或match方法返回的结果,要提取字符串,就要使用到group方法或groups方法
group方法的默认参数group1=0,等于0表示啥呢,看下面。
match或search方法通过正则表达式获取结果,结果默认为一个元组,你可以在正则表达式加一个小括号,结果也相同。
r1 = re.search('\d\w', s) 等价于 r1 = re.search('(\d\w)', s)
group1=0就表示返回的最完整的这个元组。但如果像下面这样:
r1 = re.search('\d(\w)', s)
(\w)就是第一个子元组,此时需要单独得到它的内容就需要让group1=1,即r1.group(1)
同样的,第n个子元组就使用使用group(n),多个子元组可以使用:group(1,2,3,n)
而groups方法,就是group方法的多个子元组形式。即groups()等价于group(1,2,3,..,n)
findall方法无需使用group方法,如果在正则表达式中使用了(),findall默认返回()中的内容。
元字符的使用
1.[xyz] :可以匹配到[ ]中的任意一个字符。
s = 'abc,acc,adc,aec,afc,ahc' # 筛选出第一个字符为a第二个字符为d或f第三个字符为c的结果 r = re.findall('a[df]c',s) print(r) # 输出结果为:['adc', 'afc']
2.[^xyz]: 匹配所有不包含x/y/z的字符
s = 'abc,acc,adc,aec,afc,ahc' # 筛选出第一个字符为a第二个字符不为d或f第三个字符为c的结果 r = re.findall('a[^df]c',s) print(r) # 输出结果为:['abc', 'acc', 'aec', 'ahc']
3.概括性的元字符
我们把一些能代表某个特定字符集合的元字符且称作概括性元字符。
- \d : 表示[0-9],即0到9的字符集合
- \D:表示[^0-9],即0-9]之外的字符集合
- \w:匹配[a-zA-Z0-9_],即所有的字母及数字及下划线的字符集合
-
s = 'abc^%234@#3$%4_' r = re.findall('[a-zA-Z0-9_]',s) print(r) 结果为:['a', 'b', 'c', '2', '3', '4', '3', '4', '_']
-
- \W:匹配[^a-zA-Z0-9_]
- \s:匹配空白性字符,即[ \f\n\r\t\v]
- \S:匹配所有非空白型字符
4.数量词——连续匹配
{n,m}:匹配指定次数
- 问题:我们知道findall每次只匹配一个字符,若我们要从字符串中提取完整的单词如从‘python34java*&php’中提取python java Php 三个单词怎么做?
- 答:使用数量词{n,m}匹配次数:{n}表示匹配n次,{n,m}表示最少连续匹配n次最多连续匹配m次。
- 如上面的例子可以使用下面方法来进行操作:
#例1:
findall('[a-zA-Z]{3,6}',‘python34java*&php’)
#运行结果:['python', 'java', 'Php']
例2:
findall('python{3,6}',‘python34java*&php’)
* :匹配0次或无限多次
s3 = 'pytho35pythondkfjpythonnn' r = re.findall('python*',s3) print(r) 结果:['pytho', 'python', 'pythonnn']
+ :匹配1次或无限多次
s4 = 'python*&pytho23498fsdpythonnnn' r = re.findall('python+',s4) print(r) 结果:['python', 'pythonnnn']
? :匹配0次或1次
s5 = 'python%$pytho(*pythonn' r = re.findall('python?',s5) print(r) 结果:['python', 'pytho', 'python']
. :一个点,表示匹配除\n之外的所有字符。比如需要匹配空格符的同时匹配字母数字等。
s9 = 'life is short, I use python' r = re.findall('life.*python',s9) print(r) 结果:['life is short, I use python']
5.贪婪与非贪婪
python语言默认是贪婪的。
贪婪性的表现,当条件为{n,m}时:
- 贪婪型最多连续匹配m个字符
- 非贪婪型最多连续匹配n个字符
非贪婪型的书写:{n,m}?
拿4中的例子来说,非贪婪型的匹配实例如:
s2 = ‘python34java*&Php’ r = re.findall('[a-zA-Z]{3,6}?',s2) print(r) 结果为:['pyt', 'hon', 'jav', 'Php']
6.边界匹配符
^ : 表示从字符串的第一个字符开始匹配一次,如‘^111’ :表示从字符串的第一个字符开始匹配符合111的字符段一次
$:表示从字符串的最后一个字符往前匹配一次,如‘111$’ :表示从字符串的最后一个字符往前匹配111,只匹配一次
\b:单词边界,如'\bcha' :表示匹配以cha开始的单词
\B:非单词边界,表示非单词边界匹配
# 单词边界匹配,不返回匹配值
s8 = 'I love you'
r = re.findall('e\b', s8)
print(r) #不返回匹配值
结果:
[]
^ 与 $ 搭配使用:整个字符串是否符合匹配条件,如‘^12345$’:匹配的字符串整个就是‘12345’
s6 = '111000111' r = re.findall('^\d{4,8}$',s6) # 对照组 print(r) r = re.findall('^\d{4,9}$',s6) # 整个字符串为4-9位的全数字则输出 print(r) 结果: [] ['111000111']
7.匹配任意字符
以下都表示任意字符
- [\s\S]
- [\w\W]
- [\d\D]
8.组的概念