Python-re模块攻略

常用匹配规则

match()

从字符串的起始位置开始匹配,返回SRE_MATCH对象

importre

#文本内容

content='WOW! Stunning sunrise seen this morning from Belle Plaine, Minnesota'

#文本长度

print(len(content))

#匹配特征

pattern='^\w!\sStunning sunrise\s\w'

result=re.match(pattern,content)

print(result)

#匹配内容

print(result.group())

#匹配范围

print(result.span())

#输出结果

68

WOW!Stunningsunriseseen

(,26)

"^"为匹配字符串的开头(对于match方法来说,可以不加,因为是必须从开始位置匹配)

"\w"表示匹配字母、数字、下划线共3位。

"\s"表示匹配空格。

设定的pattern中,仅匹配sunrise后+空格(\s)+4个字母(\w)。

group()方法,返回了匹配的结果。

span()方法返回了匹配的范围。

提取匹配字段

如上文中,想提取sunrise和seen,可以通过将想提取的子字符串用"()"括起来

pattern='^\w!\sStunning (sunrise)\s(\w)\s\w\s\w'

然后通过group()方法调用分组索引

>>>print(result.group(1))

sunrise

>>>print(result.group(2))

seen

Tips小技巧:为了简化print某些对索引的输出,我们可以使用匿名表达式

f=lambda x:print(result.group(x))

f(1)会是什么结果呢?

通用匹配

在pattern中,我们对于"\s"空格和"\w"的多次切换使用,大多时候其实是冗余操作,因此,需要用到".*"进行任意字符匹配,这里从头开始匹配结尾到Minnesota。

pattern='^\w!\sStunning (sunrise).*Plaine$'

#输出结果

f=lambdax:print(result.group(x))

f(1)

sunrise

f(2)

morning

"."可以匹配任意字符(除换行符),指定re.DOTALL标记可以匹配包括换行符在内任意字符

"*"可以匹配前面的字符无限次数,与"."组合即无限匹配

贪婪与非贪婪

什么是贪婪,这里另外举例子,如果我们想匹配数字,可能,开始想这样设计匹配特征

content='Hello 1234567 World'

pattern='^He.*(\d+).*ld'

print(result.group(0))

Hello 1234567 World

print(result.group(1))

7

发现结果只有匹配到7,这是因为".*"优先匹配了最多的字符,然后才轮到(\d+)

所以此时可以转换为非贪婪匹配,在".*"后多增加个"?"

pattern='^He.*?(\d+).*ld'

使用非贪婪匹配的时候,必须注意,在结尾使用".*?",意味着,尽可能少会少到不匹配。

修饰符

在正则表达式使用时,常常会遇到一些问题。比如,字符串换行时,发现无法匹配了

content='''Hello 123456

World'''

pattern='^He.*?(\d+).*ld'

Traceback (most recent call last):File "", line 1, inFile "", line 1, inAttributeError: 'NoneType' object has no attribute 'group'

原因是"."不能匹配换行符,所以我们这里需要使用re.S修饰,来使"."可以对换行符进行匹配

result=re.match(pattern,content,re.S)

print(result.group(1))

123456

转义匹配

对于内容中,如果本身就含有"."之类特殊字符,对这些字符进行匹配则需要用到"\"

search()

相对match()仅能从头开始匹配,search()方法允许返回整个字符串第一个匹配的特征。

google

findall()

需要通过一个特征匹配多组数据,findall()方法可以返回整个字符串所匹配的所有数据到列表中。

importrequests,re

headers= {

'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'

}

website='https://www.bilibili.com/read/home'

rget=requests.get(website,headers=headers,timeout=3)

pattern='(.*?)

(.*?)

'

results=re.findall(pattern,rget.text,re.S)

print(results)

B站,你懂的,总有几个感觉不易于消化的内容,不放上来了,返回的是列表形式。

sub()

将匹配的字符串直接进行替换,既可以用字符串提供的replace()方法,也可以使用re模块的sub()方法

使用方法:sub(repl, string[, count])

content='u 24a0r1e 9a4 ge3n3i123u55s'

content=re.sub('\d+','',content)

自己动手

提一点,在html,xml等等作为content层面上的应用,可以通过方法将上级节点去掉,即替换为空

,'|'表示或。

count表示最多替换次数

compile()

将一段正则表达式编译为pattern对象,并且可以传入修饰符,如re.S,从而不需要在使用search()、findall()等方法时再传入re.S了

importre

content1='2018-09-16 12:00:00'

content2='''2018-09-17 12:00:00

2018-09-18 12:00:00'''

pattern=re.compile('\d:\d:\d',re.S)

pattern='\d:\d:\d'

result1=re.sub(pattern,'',content1)

result2=re.sub(pattern,'',content2)

print('r1:\nr2:'.format(result1,result2))

r1:2018-09-16r2:2018-09-172018-09-18

split()

由于某些情况需要按照某些特征作为分隔符,提取为列表数据,使用split()

importre

content='''2018-09-17 12:13:14

2018-09-18 12:18:07'''

pattern=re.compile('-|\s|:',re.S)

result=re.split(pattern,content)

print(result)

['2018', '09', '17', '12', '13', '14', '2018', '09', '18', '12', '18', '07']

针对时间的"-","空格",":"作为分隔符提取

实际上\s并不需要,re.S也不需要,仅做列出方案

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180917G0P1GU00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券