Python正则表达式详解:语法、re模块方法与实战示例
本文系统介绍Python中正则表达式的基础语法、匹配原理及re模块的核心方法。详细解析贪婪与非贪婪模式的区别,列举compile、match、search、findall等常用函数的参数与返回值,并通过代码示例展示匹配对象的使用,帮助开发者高效处理字符串匹配任务。
正则表达式
正则表达式用于匹配特定的字符串模式。
正则表达式的匹配执行流程
- 系统会依次提取正则表达式中的字符与目标文本中的字符串进行比对。
- 若所有字符均能成功匹配,则判定匹配成功;一旦遇到无法匹配的字符,则立即判定匹配失败。
- 当正则表达式中包含量词或边界匹配符时,匹配过程会涉及更复杂的逻辑判断。
正则表达式的语法规则
语法 |
说明 |
表达式实例 |
匹配字符串 |
字符 |
|||
| . | 匹配除换行"\n"外的任意字符串 | abc | abc |
| \ | 转义字符,使后一个字符改变原来的意思 | a\\c | a\c |
| [...] | 字符集,对应的位置可以是字符集中任意字符,字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。第一个字符如果是^则表示取反,如[^abc]表示不是abc中的其他字符。所有的特殊的字符在字符集中都失去其原有的特殊含义。在字符集中使用^、]或-,可以使用转义字符匹配它们 | a[bcd]e |
abe ace ade |
预定义字符集 |
|||
| \d | 数字:[0-9] | a\dc | a1c |
| \D | 非数字:[^0-9] | a\Dc | abc |
| \s | 空白字符:[<空格>\t\r\n\f\v] | a\sc | a c |
| \S | 非空白字符:[^\s] | a\Sc | abc |
| \w | 单词字符:[a-zA-z0-9_] | a\wc | abc |
| \W | 非单词字符:[^\w] | a\Wc | a c |
数量词 |
|||
| * | 匹配一个字符串0或无限次 | abc* |
ab abc abccc |
| + | 匹配一个字符串1次或无限次 | abc+ |
abc abccc |
| ? | 匹配一个字符串0次或1次 |
abc? |
ab abc |
| {m} | 匹配一个字符串m次 | abc{2} | abcc |
| {m,n} | 匹配一个字符串m到n次 | abc{2,3} |
abcc abccc |
边界匹配 |
|||
| ^ | 匹配字符串开头 | ^abc | abc |
| $ | 匹配字符串末尾 | abc$ | abc |
| \A | 匹配字符串开始 | \Aabc | abc |
| \Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 | abc\Z | abc |
| \b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 | ||
| \B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 | ||
逻辑分组 |
|||
| | | 匹配|表达式左右的任意一个 | abc|def |
abc def |
| (...) | 作为分组,每遇到一个(,分组编号加1,使用分组的好处是匹配的子串会保存到一个子组,便于以后使用 | (abc){2} | abcabc |
| (?P<name>...) | 分组除原有编号外,再加一个别名 | (?P<id>abc){2} | abcabc |
| \<number> | 引用编号为number的分组匹配到的字符串 | (\d)ab\1 |
1ab1 5ab5 |
| (?P=name) | 应用别名为name的分组匹配到的字符串 | (?P<id>abc)ee(?P=name) | abceeabc |
特殊构造(不分组) |
|||
| (?:...) | (...)的不分组版本,用于|或后接数量词 | (?:abc){2} | abcabc |
| (?iLmsux) | iLmsux中的每个字符代表正则表达式的一种匹配模式,只能用在正则表达式开头,可选多个 | (?i)abc | AbC |
| (?#...) | 将#后面的字符当做注释忽略 | abc(?#comment)def | abcdef |
| (?=...) | 之后的字符串表达式需要匹配才能成功,不消耗字符串内容 | a(?=\d) | 后面是数字的a |
| (?!...) | 之后的字符串表达式需要不匹配才能成功,不消耗字符串内容 | a(?!\d) | 后面不是数字的a |
| (?<=...) | 之前的字符串表达式需要匹配才能成功,不消耗字符串内容 | (?<=\d)a |
前面是数字的a |
| (?<!...) | 之前的字符串表达式需要不匹配才能成功,不消耗字符串内容 | (?<!\d)a | 前面不是数字的a |
|
(?(id/name)yes_ pattern|no_parttern) |
如果匹配到分组为id或别名name的字符串成功匹配,则需要匹配yes_pattern 不成功,怎需要匹配no_pattern |
(\d)abc(?(1)\d|def) |
1abc3 abcdef |
贪婪模式与非贪婪模式的差异
贪婪模式旨在尽可能多地匹配字符串,Python默认采用此模式;非贪婪模式则尽可能少地匹配,通过在正则表达式后添加问号(?)来启用。例如:对于字符串“abcccb”,使用贪婪模式正则“ab.*c”将匹配结果“abccc”,而使用非贪婪模式正则“ab.*?c”将匹配结果“abc”。再如字符串“abbb”,贪婪模式正则“ab?”匹配结果为“ab”,而非贪婪模式正则“ab??”匹配结果为“a”。
Python中的re模块
re模块提供的主要方法如下:
1. compile(pattern[, flag]):对正则表达式pattern进行预编译,编译后的对象在多次查找时比直接使用字符串模式速度更快。
2. match(pattern, string[, flag]):从字符串string的起始位置开始尝试匹配。若匹配成功,返回匹配对象;否则返回None。注意:None对象没有group()和groups()方法,若未判断直接调用这两个方法,将引发异常。
3. search(pattern, string[, flag]):在整个字符串string中查找第一个匹配项。若匹配成功,返回匹配对象;否则返回None。
4. findall(pattern, string[, flag]):在字符串string中查找正则表达式模式pattern的所有非重复出现情况,返回包含所有匹配结果的列表。
5. finditer(pattern, string[, flags]):功能与findall()相同,但返回的是迭代器而非列表;该迭代器为每个匹配项返回一个匹配对象。
6. split(pattern, string, max=0):根据正则表达式pattern中的分隔符将字符串string分割为列表,返回成功匹配的分割结果。最多分割max次(默认为分割所有匹配位置)。
7. sub(pattern, repl, string, max=0):将字符串string中所有匹配正则表达式pattern的部分替换为字符串repl。若未指定max值,则对所有匹配位置进行替换。
匹配对象(Match Object)的方法和属性:
- string:用于匹配时的原始文本。
- re:匹配时使用的编译后的pattern对象。
- group(num=0):返回完整的匹配对象,或返回指定编号num的子组内容。
- groups():返回包含所有匹配子组的元组;若未成功匹配,则返回空元组。
参数flag:用于控制匹配行为的标志位。
| re.I | 使匹配对大小写不敏感 |
| re.L | 做本地化识别(locale-aware)匹配 |
| re.M | 多行匹配,影响 ^ 和 $ |
| re.S | 使 . 匹配包括换行在内的所有字符 |
| re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
| re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
Python使用正则表达式的实际示例
>>> import re
>>> pattern = re.compile(r'foo')
>>> res1 = re.search(pattern,'foo')
>>> res1.group() # 返回的是匹配对象,需要调用group()方法,显示所有的匹配对象
'foo'
>>> res1.groups()# 因为没有子组(即正则表达式中没有分组),返回空元组
()
>>> res2 = re.findall(pattern,'foobbfoo')
>>> res2 # 直接返回的是一个列表,包含所有匹配的字符
['foo', 'foo']
>>> pattern2 = re.compile(r'(\d+)aa')
>>> res3 = re.search(pattern2,'bb32aa')
>>> res3.group() # 返回所有的匹配的对象
'32aa'
>>> res3.groups() # 对比res1的groups(),正则里有分组,返回匹配到的分组
('32',)
>>> res4 = re.findall(pattern2,'bb32aacc5aacc')
>>> res4 # 对比res2,返回一个列表,但只包含所匹配分组里面的字符,
['32', '5']
总结
以上介绍了Python正则表达式的基本概念及re模块的使用示例,希望能为读者提供帮助。如有任何疑问,欢迎留言,小编会及时回复。感谢大家对本站的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













