- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python正则表达式教程之三:贪婪/非贪婪特性由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
之前已经简单介绍了Python正则表达式的基础与捕获,那么在这一篇文章里,我将总结一下正则表达式的贪婪/非贪婪特性。 。
贪婪 。
默认情况下,正则表达式将进行贪婪匹配。所谓“贪婪”,其实就是在多种长度的匹配字符串中,选择较长的那一个。例如,如下正则表达式本意是选出人物所说的话,但是却由于“贪婪”特性,出现了匹配不当:
1
2
3
|
>>> sentence
=
"""You said "why?" and I say "I don't know"."""
>>> re.findall(r
'"(.*)"'
, sentence)
[
'why?" and I say "I don\'t know'
]
|
再比如,如下的几个例子都说明了正则表达式“贪婪”的特性:
1
2
3
4
5
6
|
>>> re.findall(
'hi*'
,
'hiiiii'
)
[
'hiiiii'
]
>>> re.findall(
'hi{2,}'
,
'hiiiii'
)
[
'hiiiii'
]
>>> re.findall(
'hi{1,3}'
,
'hiiiii'
)
[
'hiii'
]
|
非贪婪 。
当我们期望正则表达式“非贪婪”地进行匹配时,需要通过语法明确说明: 。
{2,5}? 捕获2-5次,但是优先次数少的匹配 。
在这里,问号?可能会有些让人犯晕,因为之前他已经有了自己的含义:前面的匹配出现0次或1次。其实,只要记住,当问号出现在表现不定次数的正则表达式部分之后时,就表示非贪婪匹配。 。
还是上面的那几个例子,用非贪婪匹配,则结果如下:
1
2
3
4
5
6
|
>>> re.findall(
'hi*?'
,
'hiiiii'
)
[
'h'
]
>>> re.findall(
'hi{2,}?'
,
'hiiiii'
)
[
'hii'
]
>>> re.findall(
'hi{1,3}?'
,
'hiiiii'
)
[
'hi'
]
|
另外一个例子中,使用非贪婪匹配,结果如下:
1
2
3
|
>>> 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次以上的单词:
1
2
3
|
>>> 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)语法相关了。这样的语法可以在分组匹配的同时,不消耗字符串!所以,正确的书写方式应该是:
1
2
|
>>> re.findall(r
'\b(\w+)\b(?=.*\b\1\b)'
, sentence)
[
'what'
,
'a'
,
'day'
]
|
如果我们需要匹配一个至少包含两个不同字母的单词,则可以使用(?!abc)的语法:
1
2
3
|
>>> 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正则表达式中关于贪婪的全部内容了,希望本文的内容对大家的学习或者使用python能能带来一定的帮助,如果有疑问大家可以留言交流,如果有疑问大家可以留言交流。下一篇文章,我会继续总结一下Python正则表达式re模块的一些API的用法,请继续关注我.
原文链接:http://blog.guoyb.com/2017/03/01/python-regex-3/ 。
最后此篇关于Python正则表达式教程之三:贪婪/非贪婪特性的文章就讲到这里了,如果你想了解更多关于Python正则表达式教程之三:贪婪/非贪婪特性的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!