正则表达式中的正向预查和负向预查是一种特殊的匹配模式,它允许我们在匹配时考虑字符出现的前后环境。正向预查和负向预查是通过特殊的语法符号来定义的,分别为正向预查符号(?=\) 和负向预查符号(?!\)。

1. 正向预查
正向预查是指在匹配过程中,只匹配满足指定条件的字符串,并不占用实际的匹配结果。它使用正向预查符号(?=\) 进行定义。例如,如果我们希望匹配一个字符串中后面紧跟着数字的字符,但并不想匹配这个数字本身,可以使用正向预查。代码示例如下:

import re

text = "apple123orange"
pattern = r"\w+(?=\d)"

result = re.findall(pattern, text)
print(result)  # 输出结果为 ['apple']
Python

上述示例中,正则表达式 r"\w+(?=\d)" 中的正向预查符号(?=\) 表示后面必须紧跟一个数字,但并不匹配这个数字。因此,只有满足这个条件的 "apple" 被匹配到,而不是整个 "apple123"。

2. 负向预查
负向预查是指在匹配过程中,只匹配满足指定条件的字符串,并不占用实际的匹配结果。它使用负向预查符号(?!\) 进行定义。例如,如果我们希望匹配一个字符串中后面不紧跟着数字的字符,可以使用负向预查。代码示例如下:

import re

text = "orange123apple"
pattern = r"\w+(?!\d)"

result = re.findall(pattern, text)
print(result)  # 输出结果为 ['orange']
Python

上述示例中,正则表达式 r"\w+(?!\d)" 中的负向预查符号(?!\) 表示后面不能紧跟一个数字。因此,只有满足这个条件的 "orange" 被匹配到,而不是整个 "orange123"。

3. 正向预查的应用场景
正向预查的主要应用场景是需要在匹配时考虑特定字符出现的条件,但又不希望这些字符出现在实际匹配结果中。例如,在提取 URL 时,我们可以使用正向预查来匹配特定域名后面的路径,而不包括域名本身。代码示例如下:

import re

text = "https://www.example.com/path"
pattern = r"(?<=https://www.example.com/)\w+"

result = re.findall(pattern, text)
print(result)  # 输出结果为 ['path']
Python

上述示例中,正则表达式 r"(?<=https://www.example.com/)\w+" 使用了正向预查符号(?<=\),表示前面必须是 "https://www.example.com/",但并不匹配这个字符串。因此,只有满足这个条件的 "path" 被匹配到,而不是整个字符串。

4. 负向预查的应用场景
负向预查的主要应用场景是需要在匹配时排除特定字符出现的条件。例如,在匹配电话号码时,我们可以使用负向预查来排除一些特殊字符。代码示例如下:

import re

text = "Phone: 123-4567890"
pattern = r"\d+(?!\-)"

result = re.findall(pattern, text)
print(result)  # 输出结果为 ['123', '4567890']
Python

上述示例中,正则表达式 r"\d+(?!\-)" 中的负向预查符号(?!-) 表示后面不能紧跟一个 "-"。因此,只有满足这个条件的数字被匹配到,"123" 和 "4567890" 都被匹配到,而不是包括 "-" 的 "123-4567890"。

正向预查和负向预查在正则表达式中起到了很重要的作用,可以灵活地处理复杂的匹配需求。但需要注意的是,正向预查和负向预查只是匹配条件,并不占用实际的匹配结果,因此在提取实际的匹配结果时需要额外的处理。