Python正则表达式:贪婪/非贪婪特性
之前已经简单介绍了Python正则表达式的基础与捕获,那么在这一篇文章里,我将总结一下正则表达式的贪婪/非贪婪特性。
贪婪
默认情况下,正则表达式将进行贪婪匹配。所谓“贪婪”,其实就是在多种长度的匹配字符串中,选择较长的那一个。例如,如下正则表达式本意是选出人物所说的话,但是却由于“贪婪”特性,出现了匹配不当:
>>> sentence = """You said "why?" and I say "I don't know".""" >>> re.findall(r'"(.*)"', sentence) ['why?" and I say "I don\'t know']
再比如,如下的几个例子都说明了正则表达式“贪婪”的特性:
>>> re.findall('hi*', 'hiiiii') ['hiiiii'] >>> re.findall('hi{2,}', 'hiiiii') ['hiiiii'] >>> re.findall('hi{1,3}', 'hiiiii') ['hiii']
非贪婪
当我们期望正则表达式“非贪婪”地进行匹配时,需要通过语法明确说明:
{2,5}?
捕获2-5次,但是优先次数少的匹配
在这里,问号?可能会有些让人犯晕,因为之前他已经有了自己的含义:前面的匹配出现0次或1次。其实,只要记住,当问号出现在表现不定次数的正则表达式部分之后时,就表示非贪婪匹配。
还是上面的那几个例子,用非贪婪匹配,则结果如下:
>>> re.findall('hi*?', 'hiiiii') ['h'] >>> re.findall('hi{2,}?', 'hiiiii') ['hii'] >>> re.findall('hi{1,3}?', 'hiiiii') ['hi']
另外一个例子中,使用非贪婪匹配,结果如下:
>>> sentence = """You said "why?" and I say "I don't know".""" >>> re.findall(r'"(.*?)"', sentence) ['why?', "I don't know"]
捕获与非贪婪
严格来说,这一部分并不是非贪婪特性。但是由于其行为与非贪婪类似,所以为了方便记忆,就将其放在一起了。
(?=abc)
捕获,但不消耗字符,且匹配abc
(?!abc)
捕获,不消耗,且不匹配abc
在正则表达式匹配的过程中,其实存在“消耗字符”的过程,也就是说,一旦一个字符在匹配过程中被检索(消耗)过,后面的匹配就不会再检索这一字符了。
知道这个特性有什么用呢?还是用例子说明。比如,我们想找出字符串中出现过1次以上的单词:
>>> sentence = "Oh what a day, what a lovely day!" >>> re.findall(r'\b(\w+)\b.*\b\1\b', sentence) ['what']
这样的正则表达式显然无法完成任务。为什么呢?原因就是,在第一个(\w+)匹配到what,并且其后的\1也匹配到第二个what的时候,“Oh what a day, what”这一段子串都已经被正则表达式消耗了,所以之后的匹配,将直接从第二个what之后开始。自然地,这里只能找出一个出现了两次的单词。
那么解决方案,就和上面提到的(?=abc)语法相关了。这样的语法可以在分组匹配的同时,不消耗字符串!所以,正确的书写方式应该是:
>>> re.findall(r'\b(\w+)\b(?=.*\b\1\b)', sentence) ['what', 'a', 'day']
如果我们需要匹配一个至少包含两个不同字母的单词,则可以使用(?!abc)的语法:
>>> re.search(r'([a-z]).*(?!\1)[a-z]', 'aa', re.IGNORECASE) >>> re.search(r'([a-z]).*(?!\1)[a-z]', 'ab', re.IGNORECASE) <_sre.SRE_Match object; span=(0, 2), match='ab'>
更多Python正则表达式:贪婪/非贪婪特性相关文章请关注PHP中文网!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Linux终端中查看Python版本时遇到权限问题的解决方法当你在Linux终端中尝试查看Python的版本时,输入python...

如何在10小时内教计算机小白编程基础?如果你只有10个小时来教计算机小白一些编程知识,你会选择教些什么�...

使用FiddlerEverywhere进行中间人读取时如何避免被检测到当你使用FiddlerEverywhere...

在使用Python的pandas库时,如何在两个结构不同的DataFrame之间进行整列复制是一个常见的问题。假设我们有两个Dat...

Uvicorn是如何持续监听HTTP请求的?Uvicorn是一个基于ASGI的轻量级Web服务器,其核心功能之一便是监听HTTP请求并进�...

攻克Investing.com的反爬虫策略许多人尝试爬取Investing.com(https://cn.investing.com/news/latest-news)的新闻数据时,常常�...

在Python中,如何通过字符串动态创建对象并调用其方法?这是一个常见的编程需求,尤其在需要根据配置或运行...
