5

以下 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 添加到我的正则表达式中。

4

3 回答 3

12

对于这些正则表达式:

m/\015\012/ms
m/\015\012/s

/m 和 /s 都没有意义。

  • /s:也.匹配\n。您的正则表达式不包含.
  • /m:在字符串中嵌入^$匹配旁边。\n您的正则表达式不包含 no^$它们的同义词。

如果您的输入句柄(套接字?)在文本模式下工作,那么确实有可能,\r\015)字符将在 Windows 上被删除。

那么该怎么办?我建议使\015字符可选,并分开

/\015?\012/

不需要 /m、/s 甚至前导m//. 那些只是货物崇拜。

于 2008-10-18T09:13:12.467 回答
3

没有魔法\n。两者\n\r总是意味着一个字符,并且在所有基于 ASCII 的平台上分别是\cJ\cM。(例外是 EBCDIC 平台(出于显而易见的原因)和 MacOS Classic(其中\n\r两者均表示\cM)。)

在 Windows 上发生的神奇之处在于,当通过标记为处于文本模式的文件句柄执行 I/O 时,在读取时\r\n被转换为\n,在写入时反之亦然。(此外,\cZ它的意思是文件结束——令人惊讶!)这是在 C 运行时库层完成的。

你需要binmode你的插座来解决这个问题。

您还应该从您的模式中删除/sand/m修饰符:因为您不使用它们修改其行为的元字符(.^/$对,分别),它们什么都不做 - 货物崇拜。

于 2008-10-18T18:06:38.737 回答
1

你为什么加/m?你是想在网上分手吗?为此,/m您需要使用正则表达式^$在正则表达式中:

my @lines = split /^/m, $big_string;

但是,如果您想将大字符串视为行,只需打开对标量的引用的文件句柄:

open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
    ... process a line
    }
于 2008-10-18T16:47:48.973 回答