以下 Perl 语句在 Unixish 机器上的行为相同。它们在 Windows 上的行为是否不同?如果是,是不是因为魔法\n?
split m/\015\012/ms, $http_msg;
split m/\015\012/s, $http_msg;
我的一个 CPAN 模块在 Win32 烟雾测试仪上出现故障。看起来这是一个 \r\n vs \n 问题。我最近所做的一项更改是将 //m 添加到我的正则表达式中。
对于这些正则表达式:
m/\015\012/ms m/\015\012/s
/m 和 /s 都没有意义。
.
匹配\n
。您的正则表达式不包含.
^
和$
匹配旁边。\n
您的正则表达式不包含 no^
或$
它们的同义词。如果您的输入句柄(套接字?)在文本模式下工作,那么确实有可能,\r
(\015
)字符将在 Windows 上被删除。
那么该怎么办?我建议使\015
字符可选,并分开
/\015?\012/
不需要 /m、/s 甚至前导m//
. 那些只是货物崇拜。
没有魔法\n
。两者\n
和\r
总是意味着一个字符,并且在所有基于 ASCII 的平台上分别是\cJ
和\cM
。(例外是 EBCDIC 平台(出于显而易见的原因)和 MacOS Classic(其中\n
和\r
两者均表示\cM
)。)
在 Windows 上发生的神奇之处在于,当通过标记为处于文本模式的文件句柄执行 I/O 时,在读取时\r\n
被转换为\n
,在写入时反之亦然。(此外,\cZ
它的意思是文件结束——令人惊讶!)这是在 C 运行时库层完成的。
你需要binmode
你的插座来解决这个问题。
您还应该从您的模式中删除/s
and/m
修饰符:因为您不使用它们修改其行为的元字符(.
和^
/$
对,分别),它们什么都不做 - 货物崇拜。
你为什么加/m
?你是想在网上分手吗?为此,/m
您需要使用正则表达式^
或$
在正则表达式中:
my @lines = split /^/m, $big_string;
但是,如果您想将大字符串视为行,只需打开对标量的引用的文件句柄:
open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
... process a line
}