大家好,我是Mr数据杨,今天我们将要探索一片既神秘又实用的领域——正则表达式!请大家跟随我一起,用生活中的例子,探索这个奇妙的世界。
想象一下,你正在通过电子邮件搜索一个名叫"Bob"的朋友,但你忘了是大写的"B"还是小写的"b"。那么,不区分大小写的匹配模式就可以排除这种困扰。如同在电子邮件搜索中输入"B/bob"一样简单。
接下来,我们将要讨论的是如何在一个巨大的文本中寻找信息。那就好比你在一篇长篇小说中寻找所有以“他们”开头,以“。”结束的句子。这就需要我们使用到字符串开头和结尾锚点匹配嵌入的换行符。
在日常生活中,我们还经常面临一种需求,那就是想让电脑不仅可以理解字母和数字,还能理解换行符。那就好比你正在扫描一本书,并希望电脑能够理解书中的段落分隔符。那么,使点元字符匹配换行符就可以帮助我们实现这个目标。
另外,为了提高代码的可读性,我们还需要在正则表达式中包含空格和注释。这就像你在烹饪时,需要在菜谱的每一步骤中添加注释一样。通过这种方式,即使你在几个月之后回头看这个菜谱,也可以快速理解每一个步骤的含义。
最后,我们还将讨论如何显示调试信息,理解字符编码的解析,以及掌握正则表达式的组合标志。这就如同你在玩一个策略类的游戏,需要了解每一个角色的技能,以及如何将这些技能有效地组合在一起。
好了,各位朋友们,让我们一起深入这个看似复杂,实则有趣并充满乐趣的正则表达式世界,开启一场探索的旅程吧!
正则表达式的标志可以修改解析行为,进一步细化模式匹配。下面是支持的正则表达式标志:
简称 | 原名 | 作用 |
---|---|---|
re.I | re.IGNORECASE | 使字母字符的匹配不区分大小写 |
re.M | re.MULTILINE | 导致字符串开头和结尾锚点匹配嵌入的换行符 |
re.S | re.DOTALL | 使点元字符匹配换行符 |
re.X | re.VERBOSE | 允许在正则表达式中包含空格和注释 |
---- | re.DEBUG | 使正则表达式解析器向控制台显示调试信息 |
re.A | re.ASCII | 为字符分类指定 ASCII 编码 |
re.U | re.UNICODE | 为字符分类指定 Unicode 编码 |
re.L | re.LOCALE | 根据当前语言环境指定字符分类的编码 |
下面是具体的举例说明:
匹配不区分大小写模式
使用 re.I 或 re.IGNORECASE 标志可以使字母字符的匹配不区分大小写。
import re
re.search('a+', 'aaaAAA')
# 输出: <_sre.SRE_Match object; span=(0, 3), match='aaa'>
re.search('A+', 'aaaAAA')
# 输出: <_sre.SRE_Match object; span=(3, 6), match='AAA'>
re.search('a+', 'aaaAAA', re.I)
# 输出: <_sre.SRE_Match object; span=(0, 6), match='aaaAAA'>
re.search('A+', 'aaaAAA', re.IGNORECASE)
# 输出: <_sre.SRE_Match object; span=(0, 6), match='aaaAAA'>
字符串开头和结尾锚点匹配嵌入的换行符
使用 re.M 或 re.MULTILINE 标志可以导致字符串开头和结尾的锚点匹配嵌入的换行符。
import re
s = 'Dynasty\nWarriors\ndynasty'
re.search('^Dynasty', s)
# 输出: <_sre.SRE_Match object; span=(0, 7), match='Dynasty'>
re.search('^Warriors', s)
# 输出: None
re.search('^dynasty', s)
# 输出: None
re.search('Dynasty', s, re.M)
# 输出: <_sre.SRE_Match object; span=(0, 7), match='Dynasty'>
re.search('Warriors$', s,
re.M)
# 输出: <_sre.SRE_Match object; span=(8, 16), match='Warriors'>
re.search('dynasty$', s, re.M)
# 输出: <_sre.SRE_Match object; span=(17, 24), match='dynasty'>
re.search('Dynasty$', s, re.M)
# 输出: <_sre.SRE_Match object; span=(0, 7), match='Dynasty'>
re.search('Warriors$', s, re.M)
# 输出: <_sre.SRE_Match object; span=(8, 16), match='Warriors'>
re.search('dynasty$', s, re.M)
# 输出: <_sre.SRE_Match object; span=(17, 24), match='dynasty'>
使点元字符匹配换行符
使用 re.S 或 re.DOTALL 标志可以使点元字符匹配换行符。
import re
re.search('Dynasty.Warriors', 'Dynasty\nWarriors')
# 输出: None
re.search('Dynasty.Warriors', 'Dynasty\nWarriors', re.DOTALL)
# 输出: <_sre.SRE_Match object; span=(0, 16), match='Dynasty\nWarriors'>
re.search('Dynasty.Warriors', 'Dynasty\nWarriors', re.S)
# 输出: <_sre.SRE_Match object; span=(0, 16), match='Dynasty\nWarriors'>
允许在正则表达式中包含空格和注释
使用 re.X 或 re.VERBOSE 标志可以允许在正则表达式中包含空格和注释。
import re
# 电话号码提取的例子
regex = r'^(\(\d{3}\))?\s*\d{4}#[-.]\d{4}$'
re.search(regex, '(022)8449.#1234')
re.search(regex, '(022)8449-1234')
# 输出: <_sre.SRE_Match object; span=(0, 9), match='8449-1234'>
re.search(regex, '(022)8449-1234', re.X)
# 输出: <_sre.SRE_Match object; span=(0, 9), match='(022)8449'>
re.search(regex, '(022) 8449-1234', re.VERBOSE)
# 输出: <_sre.SRE_Match object; span=(0, 10), match='(022) 8449'>
显示调试信息
使用 re.DEBUG 标志可以使正则表达式解析器向控制台显示调试信息。
import re
re.search('Dynasty.Warriors', 'DynastyxWarriors', re.DEBUG)
字符编码解析
可以使用 re.A 或 re.ASCII 标志指定字符分类的 ASCII 编码。
可以使用 re.U 或 re.UNICODE 标志指定字符分类的 Unicode 编码。
可以使用 re.L 或 re.LOCALE 标志根据当前语言环境指定字符分类的编码。
import re
# 梵文字符串
s = '\u0967\u096a\u096c'
s
# 输出: '१४६'
re.search('\d+', s)
# 输出: <_sre.S
RE_Match object; span=(0, 3), match='१४६'>
# 德文字符串
s = 'sch\u00f6n'
s
# 输出: 'schön'
re.search('\w+', s, re.ASCII)
# 输出: <_sre.SRE_Match object; span=(0, 3), match='sch'>
正则表达式的组合标志
可以在函数调用中使用 <flags>
组合参数,通过按位 OR (|) 运算符组合标志值。
re.search('^Warriors', 'Dynasty\nWarriors\ndynasty', re.I|re.M)
# 输出: <_sre.SRE_Match object; span=(4, 7), match='Warriors'>
也可以在正则表达式中使用 (?<flags>)
来设置和清除标志值,其中 <flags>
是 a、i、L、m、s、u 和一个或多个字母 x。
字母 | 标志 |
---|---|
a | re.A、re.ASCII |
i | re.I、re.IGNORECASE |
L | re.L、re.LOCALE |
m | re.M、re.MULTILINE |
s | re.S、re.DOTALL |
u | re.U、re.UNICODE |
x | re.X、re.VERBOSE |
下面是使用等效方法设置 IGNORECASE 和 MULTILINE 标志的示例:
re.search('^Warriors', 'Dynasty\nWarriors\ndynasty', re.I|re.M)
# 输出: <_sre.SRE_Match object; span=(8, 16), match='Warriors'>
re.search('(?im)^Warriors', 'Dynasty\nWarriors\ndynasty')
# 输出: <_sre.SRE_Match object; span=(8, 16), match='Warriors'>