1. 介绍
正则表达式是一种强大的模式匹配工具,用于处理文本数据。在Python中,我们使用re
模块来操作正则表达式。
2. 基本语法
建议先看
"5. re模块函数 "了解search 和match 的区别"和
2.3 特殊字符转义"了解如何应对特殊符号
2.1 字符匹配
.
: 匹配任意字符(除了换行符\n
)
python
import re
pattern = re.compile(r"he..o")
result = pattern.match("hello")
print(result.group())
Output: hello
-
[]
: 匹配方括号内的任一字符pythonpattern = re.compile(r"[aeiou]") result = pattern.search("Hello") print(result.group())
Output: e
注意:方括号内的字母之间无需空格,因为空格算一个字符,也会参与匹配
-
|
: 匹配两个或多个模式之一pythonpattern = re.compile(r"cat|dog") result = pattern.search("I love my cat") print(result.group())
Output: cat
2.2 重复匹配
-
*
: 匹配前一个字符0次或多次 -
+
: 匹配前一个字符1次或多次 -
?
: 匹配前一个字符0次或1次pythonpattern = re.compile(r"go*gle") result = pattern.match("gooogle") print(result.group())
Output: gooogle
2.3 特殊字符转义
使用\
转义特殊字符,如.
、*
、+
等
3. 弱进阶用法
敲黑板:groups() 用于返回捕获组 的匹配结果元组,
而 group() 用于返回整个匹配结果或指定编号的捕获组的匹配结果 。
要注意的是,捕获组编号从 1 开始计数,而不是从 0 开始。
3.1 分组和捕获
使用圆括号 ()
进行分组和捕获
python
pattern = re.compile(r"(\d+)-(\d+)-(\d+)")
result = pattern.match("2023-11-15")
print(result.groups())
Output: ('2023', '11', '15')
当内容很重要时,捕获以后可以 方便后面引用
3.2 非捕获组
有时我们需要分组但不捕获,可以使用 (?:...)
。
python
pattern = re.compile(r"Mr (?:John|Doe)")
result = pattern.match("Mr John")
print(result.group())
Output: Mr John
不重要的内容无需捕获,可以提高程序性能,减少资源占用
3.3 向后引用
使用\1
、\2
等引用前面捕获的组的内容(再次强调:是内容,而不是格式)
python
pattern = re.compile(r"(\d+)-\1")
result = pattern.match("2023-2023")
print(result.group())
Output: 2023-2023
4. 匹配开始和结尾
-
^
: 匹配字符串的开始 -
$
: 匹配字符串的结尾pythonpattern = re.compile(r"^Hello") result = pattern.match("Hello, World!") print(result.group())
Output: Hello
python
pattern = re.compile(r"(World!$)")
result = pattern.search("Hello, World!")
print(result.group())
Output: World!
在正则表达式中,^ 用于匹配一行的开头 ,而不是整个文本的开头,当使用 ^ 放在正则表达式的开头时,它表示该模式只匹配行的开头位置 。
换句话说,模式必须在行的开头出现才能匹配成功
例如,如果你有一个多行的字符串,每行以数字开头,你可以使用 ^\d 来匹配每行的开头数字。
$ 匹配字符串的结尾,同理
5. re模块函数
re.match()
: 从字符串的开头匹配模式re.search()
: 在字符串中查找匹配模式的第一个位置re.findall()
: 返回字符串中所有匹配的模式re.sub()
: 替换字符串中匹配模式的部分
6. 贪婪与非贪婪匹配
在重复匹配时,加上?
可以实现非贪婪匹配。
python
pattern = re.compile(r"<.*?>")
result = pattern.search("<html><head><title>Title</title></head></html>")
print(result.group())
Output:
默认情况下,正则表达式是贪婪匹配 ,也就是它会尽可能地匹配最长的字符串 。贪婪匹配会将模式中的量词(如 *、+、?、{})设置为尽可能多地匹配字符。例如,正则表达式 a.*b 可以匹配 "afoobarb" 中的整个字符串,而不只是 "a" 和 "b" 之间的部分。
相比之下,非贪婪匹配 是匹配尽可能少的字符 。它使用量词的非贪婪版本来实现。在正则表达式中,非贪婪模式的量词是加上 ? 符号。例如,a.*?b 是一个非贪婪匹配模式,它只匹配 "a" 和 "b" 之间的最短字符串。对于 "afoobarb",匹配结果将是 "afoob"。
7. 预搜索
-
(?=...)
: 正向预查 -
(?!...)
: 负向预查pythonpattern = re.compile(r"\d+(?=%)") result = pattern.search("42%") print(result.group())
Output: 42
正向预查 (?=...) 表示在匹配当前位置之后的内容时,需要满足 ... 的条件。但是,正向预查不会消耗字符串,也不会将预查的内容包含在匹配结果中。
负向预查 (?!..) 则表示在匹配当前位置之后的内容时,需要不满足 ... 的条件才能匹配成功。与正向预查类似,负向预查也不会消耗字符串,也不会将预查的内容包含在匹配结果中。
相当于先判断后面的字符串是否符合条件决定是否匹配