【python】正则表达式:贪婪模式、非贪婪模式以及修饰符

什么是正则表达式

【简介】:正则表达式(Regluar Expressions)又称规则表达式,用来判断文本的格式。用正则表达式可以指定想要匹配的字符串规则,然后通过这个规则来匹配、查找、替换或切割那些符合指定规则的文本。

【本质】正则表达式本质上是一个小巧的、高度专用的编程语言。 许多程序设计语言都支持通过正则表达式进行字符串操作。

主要功能如下:

  • 【匹配验证】:判断给定的字符串是否符合正则表达式所指定的过滤规则,从而可以判断某个字符串的内容是否符合特定的规则(如email地址、手机号码等);

【注意点】:当正则表达式用于匹配验证时,通常需要在正则表达式字符串的首部和尾部加上^和$,以匹配整个待验证的字符串。

  • 查找与替换: 判断给定字符串中是否包含满足正则表达式所指定的匹配规则的子串,如查找一段文本中的所包含的IP地址。另外,还可以对查找到的子串进行内容替换。

  • 字符串分割与子串截取:基于子串查找功能还可以以符合正则表达式所指定的匹配规则的字符串作为分隔符对给定的字符串进行分割

【知识点补充】:正则表达式的语法是由正则表达式引擎决定的(目前主流的正则引擎分为3类:DFA、传统型NFA 和 POSIX NFA),不同编程语言或应用程序所使用的引擎可能不同,它们对正则表达式的语法支持会有差别。


常用的一些正则表达式-汇总

【程序】

import re
tel_reg = "^1[^0-9]{10}$"
r = re.match(tel_reg,'18222203932')
if r:
    print(r.group())
    print(r.span())
else :
    print("电话号码不合法")

输出:
电话号码不合法
match()

从字符串的起始位置匹配正则表达式。如果匹配成功,就返回匹配结果,否则返回None

  • match:从字符串的开头开始匹配,如果一开头不匹配,就会导致失败。
  • match一般用来判断文本的格式是否合法。
  • ^ 以..开始,$ 代表..结束
  • ^ 用在[]中,代表排除。
  • [^a-z] 表示不能是小写的a-z
  • 量词:表示规定文本出现的次数。例如:{10} 出现10次。{1,}代表出现1次以上。 {1,10} 出现1-10次。

【实例】

mail_reg = '\w+@\w+\.(com|org|net)'
tel_reg = "^1\d{10}$"
r = re.match(mail_reg,'98098323@qq.org')
if r:
    print(r.group(0))
    print(r.group(1))
    print(r.span())
else :
    print("邮箱格式不合法")

---
输出:
98098323@qq.org
org
(0, 15)

【解释】() 可以对正则表达式进行分组,group(0)或者group()返回的是整个正则表达式的内容。group(n) 返回的是第n个组中的内容,n从1开始。

关于字符串的一些用法
语法 用法 等价
\d 匹配任意一个数字字符 [0-9]
\D 匹配任意一个数字字符 [0-9]
\s 匹配任意一个空白字符串 [t\n\d\f\h]
\S 匹配任意一个非空白字符串 [^\t\n\d\f\h]
\w 匹配任意一个alphanumeric character [a-z,A-Z,0-9]
\W 匹配任意一个non-alphanumeric [a-z,A-Z,0-9]

关于贪婪模式和非贪婪模式

一句话解释:

  • 贪婪模式,默认情况下,会尽可能多的匹配符合正则的文本。
  • 非贪婪模式,会尽可能多的给下一个匹配正则留出文本。

下面来看两张图:


贪婪模式匹配过程分析
非贪婪模式匹配过程分析

举个栗子:

content = "hello 12324 world, this is a Demo regex"
reg = "^He.*?(\d+).*regex"
r = re.match(reg,content,re.I)
if r:
    print(r.group())
    print(r.group(1))
else :
    print("没有匹配")


输出:
hello 12324 world, this is a Demo regex
12324

【总结】贪婪模式与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配;非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。

【补充】非贪婪模式只被部分NFA引擎所支持。从匹配效率上来看,能达到相同匹配结果时,贪婪模式的匹配效率通常会比较高,因为它回溯过程会比较少。


关于修饰符

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 来指定。详细介绍见下表所示

修饰符 描述
re.I 忽略大小写
re.S 使.可以匹配包括换行符在内的所有字符
re.L 本地化识别(lacale-aware) 匹配
re.M 多行匹配,影响 ^ 和 $
re.U 根据Unicode字符集解析字符
re.X 通过给与更灵活的格式以便将正则表达式写的更便于理解

【示例】

reg = 'w{3}\..+\.com\?.*'
reg = "^www\.baidu\.com\?key=dasda$"
content = "www.baidu.com?key=dasda"
r = re.match(reg,content)
print(r)

# search():扫描整个字符串,返回第一个匹配结果
content = "aaa121aad323ddd"
reg = '\d+'
r = re.search(reg,content)
r
print(r.group())

输出:
<re.Match object; span=(0, 23), match='www.baidu.com?key=dasda'>
121

# findall() 可以返回所有匹配的字符串
r = re.findall(reg,content)
print(r)

输出:
['121', '323']

看了那么多的讲解...
下面我们来用正则表达式处理一下网易云音乐的一部分源代码,并筛选出歌曲名称。
源码(部分)如下:

html = '''
<ol>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no no-top">1</span>
<a href="/song?id=1374483648" class="nm s-fc0 f-thide" title="Beautiful People (feat. Khalid)">Beautiful People (feat. Khalid)</a>
<div class="oper">
</div>
【中间部分太多...部分省略】
</li>
<li onmouseover="this.className='z-hvr'" onmouseout="this.className=''" class="">
<span class="no">10</span>
<a href="/song?id=1361615183" class="nm s-fc0 f-thide" title="你在哪里">你在哪里</a>
<div class="oper">
<a href="#" class="s-bg s-bg-11" title="播放" hidefocus="true" data-res-type="18" data-res-id="1361615183" data-res-action="play" data-res-from="31" data-res-data="19723756"></a>
</li>
</ol>
'''

处理过程:

reg = "<li.*?<a href.*?>(.*?)</a>"
r = re.findall(reg,html,re.S)
if r:
    for song in r:
       print("【",song,"】")

# sub()用来替换符合格式的内容
content = '12fdf322fdsfjj323njjdsjkf'
reg = '\d+'
r = re.sub(reg,'',content)
print(r)

输出歌曲名称:

【 Beautiful People (feat. Khalid) 】
【 Heartbeat (BTS WORLD OST) 】
【 I Fell In Love With The Devil (Radio Edit) 】
【 你好 】
【 晚安 】
【 平胸女子 】
【 憾 】
【 Room to Fall 】
【 キスだけで 】
【 你在哪里 】

【知识补充】
  • 时间匹配:compile()

  • sub():用来替换符合格式的内容

【示例】

content = 'Zurich19982321426.Alacazar'
reg = '\d+'
r = re.sub(reg,'',content)
print(r)

c1 = "2019-6-29 14:10"
c2 = "2016-9-13 17:40"
p = re.compile("\d{2}:\d{2}")
print(re.sub(p,'',c1))
print(re.sub(p,'',c2))

输出:

Zurich.Alacazar
2019-6-29 
2016-9-13 

【参考】关于正则表达式的文章:
https://www.cnblogs.com/yyds/p/6913550.html
https://blog.csdn.net/luanpeng825485697/article/details/78386400

正则表达式汇总(来源网络)感谢感谢,这张表总结的很全了~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 搞懂Python 正则表达式用法 Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一...
    厦热阅读 1,537评论 0 2
  • 本篇将介绍python正则表达式,更多内容请参考:【python正则表达式】 什么是正则表达式 正则表达式,又称规...
    小七奇奇阅读 312评论 0 5
  • 目录 [1、 什么是正则表达式. [2、 正则表达式语法结构. [2.1. 入门案例:了解正则表达式. [2....
    _宁采臣阅读 928评论 0 3
  • 明天休息,今天放松下,来到了孟老师之前经常来的KTV,一起嗨,一起放松。五音不全。酒,自然填充了我的需要。拿起酒,...
    娚稀妹子阅读 209评论 0 2
  • 2017.10.09 排毒 早上称重 51.0kg 早上 一杯蜂蜜水 小份枸杞 中午 小份枸杞 下午 一杯大麦若叶...
    9月17日阅读 143评论 0 0