Python 的正则表达式支持 多行模式,将每行文字分别匹配。然而各种操作系统里,换行符的表示法各不相同,会导致 Python 不能正确使用多行模式。
花式换行符
不同操作系统下, 换行符的表示方法 也不同。主要有以下三种:
操作系统
换行符名称
16 进制值
10 进制值
转义表示
Unix、Linux
LF
0A
10
n
Windows、DOS
CR LF
0D 0A
13 10
r n
Mac
CR
0D
13
r
测试 Python 的表现
如果 Python 不能正确识别换行符,就无法按照期望,进入多行模式的匹配模式。
可以使用下面的脚本来检验各种换行符下,不同版本Python 能否正确进入多行模式。脚本如下:
import re
print(re.findall(r"^w+$", "hellornbyern", re.M))
如果结果是 ['hello', 'bye'] ,说明正确进入了多行模式;而如果结果是 [] , 则说明没有正常进入多行模式。
测试结果
操作系统
换行符表示
Python 2.7
Python 3.6
Unix、Linux
n
['hello', 'bye']
['hello', 'bye']
Windows、DOS
r n
[]
[]
Mac
r
[]
[]
测试结果说明,只有 n 这种换行符能成功将 Python 带入 多行模式。
如何分辨换行符
那么面对传来的字节流,无论是来自文件、网络,如何知道其中的换行符是 上节 中的那种呢?我们需要以将字符串用二进制形式表达。
下面这个脚本可以观察字节流的二进制表示:
s=["hellon","hellorn","hellor"]
for y in s: print(' '.join(format(ord(x), 'b') for x in y))
得到结果为:
1101000 1100101 1101100 1101100 1101111 1010 #n
1101000 1100101 1101100 1101100 1101111 1101 1010 #rn
1101000 1100101 1101100 1101100 1101111 1101 #r
如何纠正
那么怎么将换行符调整到 适合 Python 进入多行模式的呢?可以使用 re.sub() 查找替换函数:
print(re.findall(r"^w+$", re.sub(r"r","n",s), re.M))
或者
print(re.findall(r"^w+$", re.sub(r"r","",s), re.M))
将所有的 r 删除或者 替换为 n ,就能正确识别出换行符。