Perl 的 /m 正则表达式修饰符在 Windows 上的匹配是否不同?
题
以下 Perl 语句在 Unixish 机器上的行为相同。它们在 Windows 上的行为是否有所不同?如果是的话,是因为 的魔力吗?
split m/\015\012/ms, $http_msg;
split m/\015\012/s, $http_msg;
我有一个 失败 在我的一个来自 Win32 烟雾测试仪的 CPAN 模块上。看起来这是一个 与 的问题。我最近所做的一项更改是将 //m 添加到我的正则表达式中。
解决方案
对于这些正则表达式:
m/\015\012/ms m/\015\012/s
/m 和 /s 都没有意义。
- /秒:使
.
匹配\n
也。你的正则表达式不包含.
- /米:使
^
和$
匹配旁边嵌入的\n
在字符串中。你的正则表达式不包含^
也不$
, ,或它们的同义词。
确实可能的是,如果您的输入句柄(套接字?)在文本模式下工作,则 \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
和 / m
修饰符:因为您不使用其修改行为的元字符(。
和 ^
/ $
对分别),他们什么都不做–货物崇拜。
为什么要添加 / m
?你想分手吗?要使用 / m
执行此操作,您需要在正则表达式中使用 ^
或 $
:
my @lines = split /^/m, $big_string;
但是,如果要将大字符串视为行,只需在对标量的引用上打开文件句柄:
open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
... process a line
}