③ findall(pattern, repl, string, count=0, flags=0)
findall()函数语法格式如下:
pattern:你写的正则表达式;
string:待匹配的字符串;
flag:修饰符;
findall()函数,不管是我们做爬虫,还是我们做数据清洗,都属于高频函数,大家一定要好好掌握。
我们先看一个简单的例子:
还是前面的字符串s1,我们分别只想获取a、只想获取b、获取a或b,使用findall()会出现什么结果呢?
s1 = 'ab黄cd同abc学' re.findall('a',s1) re.findall('b',s1) re.findall('[a | b]',s1)
结果如下:
可以发现:finadll()函数会直接返回所有匹配对象,组成的列表(记住:返回的是列表),不像search()函数与match()函数,还需要调用group()函数,这个大家一定要注意。
如果finadll()函数,没有匹配上,不会报错,而是返回一个空列表。
s1 = 'ab黄cd同abc学' re.findall('f',s1)
结果如下:
我们在来看一个稍微复杂一点的案例(爬虫经常见到的)
html = '''<html> <head lang="en"> <title>Title</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id="content"> <ul id="ul1"> <li>first</li> <li>second</li> <li>third</li> </ul> <ul id="ul2"> <li>alpha</li> <li>beta</li> </ul> </div> <div id="url"> <a href="http:www.baidu.com" title="baidu">baidu</a> <a href="http:www.tipdm.com" title="tipdm">tipdm</a> </div> </body> </html> '''
如果我们想要使用正则表达式,获取其中的li标签,或者获取其中的href属性,应该怎么做呢?
# 获取li标签 re.findall('<li>(.*?)</li>',html) # 获取href属性 re.findall('<a href="(.*?)" ',html)
结果如下:
操作其实很简单,固定写法:首尾照抄字符串源代码,我们想要的东西使用()小括号,括起来,里面写上 .*?
上面提到了一个.*与.*?,其中.*表示贪婪匹配,.*?表示非贪婪匹配。
. 可以匹配除了换行符以外的所有字符;
*表示匹配前面的字符无限次;
?前面紧挨的元素,最多匹配一次;
我们用一个例子简单说明:
s2 = 'a123b456b789b3' re.findall('a(.*)3',s2) re.findall('a(.*?)3',s2)
结果如下:
用一句通俗的话说明它们的区别:贪婪匹配是尽可能多的匹配内容,非贪婪匹配是尽可能少的 匹配内容。字符串s2中有两个3,贪婪匹配会一直匹配到最后一个3,但是非贪婪匹配找到第一个3后,就停止了。
④ compile()
compile函数将字符串编译成正则表达式对象,供 match() 、 search() 和findall()函数使用。
即:先定义一个正则表达式对象(Pattern对象),然后分别调用该对象的match() 、 search() 和findall()函数,这三个函数用法与它们原本用法相同。
我们直接用一个例子讲述该函数:
type(re.compile(r'\d+'))
结果如下:
可以看到这是一个Pattern对象。
s3 = '12one34two56three78four' # 定义一个正则表达式对象,用于匹配至少一个数字 pattern = re.compile(r'\d+') # 扫描整个字符串,匹配s3字符串中,符合该正则表达式的字符串。(这里调用的是对象的findll()对象)。 pattern.findall(s3) # 从s3字符串,下标为1的位置,查找匹配值。 pattern.findall(s3,1) # 从s3字符串,下标为1到下标为6的位置之间,查找匹配值。 pattern.findall(s3,1,6)
结果如下:
⑤ sub(pattern, repl, string, count, flags)
sub()函数是Python正则表达式中,专门用于“替换”的函数。
sub()函数语法格式如下:
pattern:你写的正则表达式;
repl:替换成啥;
string:待替换的字符串;
count:表示最大替换次数,默认 0 表示替换所有的匹配;
flag:修饰符;
同样对于上述提到的字符串s3,我们将“英文字母” 全部替换为 “字母”两个字,应该做么办呢?
# '\D{3,5}'表示匹配非数字3-5次。 s3 = '12one34two56three78four' # 这里没有指定最大匹配次数,因此默认会替换所有的匹配值 re.sub('\D{3,5}','字母',s3) # 这里指定最大匹配次数count=2,因此只会替换前2个匹配值 re.sub('\D{3,5}','字母',s3,2) # 如果count=3,则会替换3个匹配值 re.sub('\D{3,5}','字母',s3,3)
结果如下:
⑥ split(pattern, string, maxsplit, flags)
split()函数是Python正则表达式中,专门用于“切分字符串”的函数。
split()函数语法格式如下:
pattern:你写的正则表达式;
string:待分割的字符串;
maxsplit:最大分割次数,默认为 0,表示不限制分割次数;
flag:修饰符;
有这样一个字符串s4,我们以“-”为分隔符切分字符串,看看使用split()函数会得到什么样的结果。
# '\D'表示匹配非数字 s4 = '136-3456-7413' # 这里如果不指定“最大分割次数”,则是不限次数切分 re.split('\D',s4) # 如果指定最大分割次数maxsplit=1,那么就只以第一个分隔符,进行切分 re.split('\D',s4,1)
结果如下:
限于篇幅!这篇文章就讲述到这里。当然,关于正则表达式中剩下的一些用法(比如说普通元字符、量化符、修饰符的用法),还有第二篇文章。