正则表达式贪婪和非贪婪
正则表达式(Regular Expression)是用于匹配字符串的语言,在编程中常常使用。贪婪和非贪婪是正则表达式的两种匹配方式,分别对应在匹配时选择尽量“多”或“少”的匹配字符。
贪婪匹配
贪婪匹配(Greedy Matching)是指匹配时,尽可能多地去匹配字符的方式。比如在正则表达式中使用“.*”会匹配任意数量的任意字符,包括空字符。例如:
import re
text = "hello abc abcdefg abcdefghijklmn"
pattern = "abc.*"
match = re.findall(pattern, text)
print(match)
# Output: ['abc abcdefg abcdefghijklmn']
代码中使用re.findall()方法对文本进行匹配,pattern为“abc.*”,表示匹配以“abc”开始,后面包含任意数量的任意字符。
运行结果输出了整个文本字符串,因为默认情况下,正则表达式是贪婪匹配的,即选择尽量多的匹配字符。
import re
text = "hello abc abcdefg abcdefghijklmn"
pattern = "abc.*n"
match = re.findall(pattern, text)
print(match)
# Output: ['abcdefg abcdefghijklmn']
另外,当指定匹配字符的范围时,也是贪婪匹配的。例如,当我们匹配从“a”开始,后面包含若干个’a’或’b’,最后匹配到一个“c”时,代码如下:
import re
text = "aabbbccc"
pattern = "a[a|b]*c"
match = re.findall(pattern, text)
print(match)
# Output: ['aabbbcc']
可以看到,输出结果为“aabbbcc”,其中匹配到了若干个’a’或’b’,直到最后一个字符是“c”为止。
非贪婪匹配
非贪婪匹配(Non-Greedy Matching)是指匹配时,尽可能少地去匹配字符的方式。在正则表达式中,可以使用“.*?”来进行非贪婪匹配。例如:
import re
text = "hello abc abcdefg abcdefghijklmn"
pattern = "abc.*?"
match = re.findall(pattern, text)
print(match)
# Output: ['abc ', 'abcdefg ', 'abcdefghijklmn']
代码中,pattern为“abc.*?”,表示匹配以“abc”开始,后面包含任意数量的任意字符,但是在匹配时,选择尽量少的匹配字符。输出结果是三个匹配结果,“abc ”、“abcdefg ”、“abcdefghijklmn”。
再看一个例子,在指定匹配字符的范围时,如果使用非贪婪匹配,那么会选择尽可能少的字符。代码如下:
import re
text = "aabbbccc"
pattern = "a[a|b]*?c"
match = re.findall(pattern, text)
print(match)
# Output: ['abc']
输出结果为“abc”,其中只有一个匹配结果,选择了尽量少的’a’或’b’,匹配到了第一个“c”。
结论
正则表达式的贪婪和非贪婪匹配的区别在于,对于尽可能多地匹配字符和尽可能少地匹配字符的选择。在编程时,需要针对实际应用场景,选择适合的匹配方式。如果需要选择尽量少的匹配字符,可以在正则表达式中使用“.*?”进行非贪婪匹配。