正则表达式的常用方法

关于正则表达式的元字符的种类,请访问 正则表达式 - 元字符

今天只是说一说使用的一些方法

一. 首先得先导入re,import re,

1. match()方法

从一个字符串的第一个字符开始匹配,也就是如果第一个字符不匹配的话,那么结果就是None了。例如

string = 'hellow 123 world'
text = re.match('^.*\d+', string)  # ^的U作用是匹配一个字符串的开头
print(text)
# 匹配到的结果: 'hellow 123'

# 没有^也一样,match()方法默认就是从第一个字符串开始匹配
text2 = re.match('.*l', string)  
# 匹配到的结果就是: 'hellow 123 worl'

# 如果想直接匹配到123串数字呢
text3 = re.match('\d+', string) 
# 匹配到的结果就是None

所以,match()这个方法比较死板,必须从第一个字符就得匹配才行,那么能不能匹配任意位置的字符串呢,当然可以。

2. search()方法

这个方法是将整个字符串中符合条件的第一个结果匹配出来

string = 'apython532 python54'
text = re.search('python\d+', string)
print(text)
# 匹配结果为:'python532'

可以看到上面例子中,可以不从string的第一个字符开始匹配,而是相当于全文搜索。但是可以看到,'python532'和'python54'都是符合匹配规则的,返回的只是第一个结果,那么如果我要想返回所有符合条件的字符串怎么办?

3. findall()方法

string = 'apython532 python54'
text = re.findall('python\d+', string)
print(text)
# 返回的结果为: ['python532', 'python54']

可以看到,使用findall()方法可以将字符串中符合匹配规则的所有子字符串都匹配出来,封装为一个列表。

4. sub()方法

我们知道,字符串有一个replace(old, new)方法,就是将字符串中的想要某个子字符串替换为新的字符串,用正则也可以做到,例如

# 例如要把string这个字符串中的数字全部去掉
string = 'j39aeq94g.309p['
# repalce()方法
text = string.replace('39', '')
text1 = text.replace('94', '')
text2 = text1.replace('309', '')
# 经过上面的步骤才能输入'jaeqg.p['这个结果

# re.sub()方法
text = re.sub('\d+', '', string)
# 输入结果:'jaeqg.p['

可以看到,直接用'\d+'匹配了字符串中的所有数字,然后直接全部替换为''空就就行了。所以正则操作字符串还是有些好处的

5. compile()方法

compile()可以将正则字符串编译成一个正则表达式的对象,可以理解成就是把在这个方法中定义的正则表达式封装成一个整体,然后可以供其他字符串使用,举个例子

t1 = '2018-08-08 09:30'
t2 = '2018-09-30 13:45'
# 那么将两个字符串中的日期(年月日)匹配出来
st = re.compile('\d+:\d+')
from_t1 = re.sub(st, '', t1)
from_t2 = re.sub(st, '', t2)
print(from_t1, from_t2)
# 结果:2018-08-08 2018-09-30

上面这个例子意思就是,先将'\d+:\d+'这种规则作为一个整体,然后在from_t1,from_t2中直接调取作为匹配的规则。那么还有一种应用就是

string = '[3ko]:http-owpd03'
# 将上面的http匹配出来
st = re.compile('\[3ko\]\:(.*?)\-.*').findall(string)
# 打印st,结果为:['http']

这里有用到贪婪非贪婪,还有转义符的使用,可以先不用理解,下面会讲到,现在只要明白compile().findall()这种结构,另外就是compile()中我们用来得到'http'的括号,那个括号里就是我们要得到的东西,括号外面的我们都不用管,只是起一个限制的作用。

二. 上面的是我常用的一些方法,或者可以理解为“框架”,然后使用时,将匹配规则套进去就行了。那么在来讲一下匹配的一些规则

1. 贪婪模式和非贪婪模式

我们知道,' . '表示匹配除换行符以外的任意字符,' * '表示可匹配多个表达式,也就是可以理解为' .* '在一起就是匹配一个字符串中除换行符以外的所有字符,所以它是贪婪模式,也就是它会尽可能的去匹配符合表达式的片段。' ? '表示匹配0个或1个前面的表达式定义的片段,所以可以理解为' ? '字符与它前面的字符在一起组成的匹配类型就是非贪婪模式,就是在你匹配的这个字符串中,它最多给你匹配一次。下面举例说明,现有一个字符串如下,

string = 'apython532 python54'

# 贪婪模式
text = re.search('.*\d', string)
# 匹配到的结果为: 'apython532 python54'

# 非贪婪模式
text2 = re.search('.*?\d', string)
# 匹配到的结果为: 'apython5'

我们来分析一下,对于贪婪模式下,.*是尽可能的匹配字符,\d是匹配一个数字,也就是'.*'的意思就是尽可能的匹配,直到匹配的最后一个字符为数字,那么在'apython'后已经有一个数字了,按理说这个时候就应该结束了,但是,由于是贪婪模式,它只要保证得到的结果的最后一个字符为数字就行,所以'.*'其实是匹配了'apython532 python5','\d'匹配了最后的一个数字4,所以整个结果就是将string全部匹配进去了。

理解了上面的贪婪模式,现在说非贪婪,非贪婪的意思在上面已经介绍过了。这儿'.*?'的意思可以理解为,只要保证我的结果的最后一个字符是数字,那么前面匹配的能少就少,结合上面的例子就是,.*?"匹配了'apython','\d'匹配了'5',所以结果为'apython5'。

2. 当匹配的目标中含有特殊字符,或者需要在特殊字符处分割,就得用转义符'\'

string = 'https://passport.csdn.net/login?from=https'

# 匹配上面的https://(passport.csdn.net?login?)from=https括号中的那一个字符串
text = re.compile('https:\/\/(.*?)from.*?').findall(string)
print(text)
# 结果为:['passport.csdn.net/login?']

我们在前面也用到过转义符,因为正则它不认识这些特殊字符,所以遇到这些特殊字符前,必要的地方就要在其前加上转义符,比如我们上面用到的\/\/这就是对这个'//'进行转义,记住,转义时每个字符都要转义。那么问题来了。上面这个字符串中不是还有. / ? =这些特殊字符吗,为什么没有进行转义呢。因为它们所处的特殊位置,它们所在的地方已经用.*代替了,而前面的https://中的//为什么不能用.*或者.*?替换呢,因为我们要匹配passport.csdn.net/login?这个字符串,所以我们放了一个括号,意思是我们要得到这个括号里的东西,但是括号外面总的有个标志性的东吧,不然谁知道你这个括号要得到什么。这种方法做爬虫时,特别是要得到一个html页面下的一类节点的属性或text时,这个方法就可以实现将得到的所有符合条件的字符串封装在一个列表返回给你。

3.最后讲一个re.S

加入我们匹配的内容在多行,那之前的方法都只能得到一行的内容,即便是贪婪模式也是举例说明

string = '''article-item-box 
csdn-tracking-statistics 
data-articleid=81162102'''
# 现在要得到articl-()8162102这个括号里的内容,
st = re.compile('article-(.*?)\d', re.S).findall(string)
# 结果为:['item-box \ncsdn-tracking-statistics \ndata-articleid=']

如果不加re.S,那么就只能得到一个空列表的了。

猜你喜欢

转载自blog.csdn.net/wtwcsdn123/article/details/82116330