Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5693760
  • 博文数量: 477
  • 博客积分: 12019
  • 博客等级: 上将
  • 技术积分: 6545
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-01 16:46
文章分类

全部博文(477)

文章存档

2020年(34)

2019年(4)

2018年(10)

2017年(5)

2016年(2)

2015年(4)

2014年(4)

2013年(16)

2012年(47)

2011年(65)

2010年(46)

2009年(34)

2008年(52)

2007年(52)

2006年(80)

2005年(22)

分类: Python/Ruby

2020-03-20 09:22:37

转自:https://www.jianshu.com/p/2207109df3df

问题

使用正则表达式匹配字符串时,返回的是最长匹配,需要修改它变成查找最短的匹配。

解决方案

这个问题,一般出现在需要匹配一对分隔符之间的文本时,比如:

import re

text1 = 'Computer says "no."' text2 = 'Computer says "no." Phone says "yes."' str_pat = re.compile(r'".*"') print(str_pat.findall(text1)) print(str_pat.findall(text2)) ['"no."'] ['"no." Phone says "yes."'] 

在例子(2)中,需求是匹配被双引号包含的文本,但是在正则表达式中*操作符是贪婪的,匹配操作会查找最长的可能匹配,返回的结果并不是我们想要的。

为了修正这个问题,可以在*操作符后面加上?修饰符,比如:

str_pat1 = re.compile(r'".*?"') print(str_pat1.findall(text2)) ['"no."', '"yes."'] 

这样就使得匹配变成非贪婪模式,从而得到最短的匹配,也就是我们想要的结果。

讨论

在正则表达式中,点(.)字符匹配除了换行外的任何字符。

如果将点(.)放在开始与结束符(比如引号)之间,匹配操作会查找符合模式的最长可能匹配,会导致很多中间的被开始与结束符包含的文本被忽略掉,并最终被包含在匹配结果字符串中返回。

==========================================================
我在实验中的例子:

ss = "献岁菊(《台湾府志》),雪莲(《西域见闻录》),长春菊(《事物绀珠》),岁菊(《漳》),冰里花、顶冰花(《东北植物药图志》),冰凉花、雪莲花(《药材学》),冰郎花(《吉林中草药》)。"

print ss

pattern = re.compile(r'((.*))')
pattern = re.compile(r'((.*?))')
#print pattern.findall(ss)
r = pattern.sub("",ss)
print r

阅读(326493) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~