python 正则匹配任意字符的一个坑

错误: .* 是匹配除了换行符\n以外的所有字符。

正确: 正确匹配任意字符的表达式应该是 [\s\S]*[\d\D]*[\w\W]*。(中括号 [] 表示字符集合,匹配集合中的任意字符。)

错误: 另一种错误表达式是 (.|\s)* 。这个乍一看是没有问题的,但在执行 findall() 匹配的时,可能会遇到无法终止的情况。举一个例子看看:

#!/usr/bin/python2
# -*- coding: utf-8 -*-

import re

content = """
START
hello, world. 123 hello, world. 123 hello, world. 123 hello, world. 123 hello, world. 123
hello, world. 123 hello, world. 123 hello, world. 123 hello, world. 123 hello, world. 123

"""

# 匹配以START开始,END结尾,中间任意字符的字符串。
# 其中 (?: ) 表示不是捕获括号内的内容。因为正则匹配遇到括号后,默认会只去捕获括号内匹配的内容
# 其中 (.|s)+? 就是我以为可以用来匹配任意字符的错误用法
result = re.findall(ur"START(?:.|\s)+?END", content)
print(result)

上诉例子就会陷入“卡死”的状态。

如果将 content 字符串用 START … END 闭合,findall 可以正常识别出内容;

如果将 content 字符串的内容减少一点,比如只留下 “START hello, world.”,findall 也能很快返回无可匹配内容;

而像上面这样,字符串一长点,并且未闭合的话,findall 就会陷入“卡死”状态。。。。

正确的做法就是把 "START(?:.|\s)+?END" 改成 "START[\s\S]+?END"

蛤?你说为什么会这样?。。。我也不知道 🤷‍♂️

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top