2008-10-18 26 views
5

以下Perl语句在Unixish机器上的行为相同。他们在Windows上表现不同吗?如果是的话,是因为魔法\ n?Perl的/ m正则表达式修饰符在Windows上的匹配方式不同吗?

split m/\015\012/ms, $http_msg; 
    split m/\015\012/s, $http_msg; 

我从我的一个Win32烟雾测试仪的CPAN模块上获得了一个failure。它看起来像是\ r \ n vs \ n问题。我最近做的一个改变是将m添加到我的正则表达式中。

回答

12

对于这些正则表达式:

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

两者/ m和/ s的是无意义的。

  • /s:使.匹配\n。 您的正则表达式不包含.
  • /m:使^$匹配嵌入的\n在字符串中。 您的正则表达式不包含^$或其同义词。

什么是可能确实是,如果你的输入句柄(插座?)在文本模式下工作时,\r\015)字符将在Windows已被删除。

那么,该怎么办?我建议把\015人物可选,并反对分裂

/\015?\012/ 

无需/ M,/ s甚至领先m//。那些只是货物崇拜。

+0

ARGH!我认为你是对的,并且我正在用正则表达式修饰符错误地跟踪。我正在使用``从子进程获取输入,并且从未想过要担心binmode ... – 2008-10-19 01:19:31

1

为什么添加/m?你在试图分裂吗?要做到这一点与/m你需要在正则表达式为使用^$

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

但是,如果你想治疗大串的线路,只需打开一个文件句柄到标量的引用:

open my $string_fh, '<', \ $big_string; 
while(<$string_fh>) { 
    ... process a line 
    } 
3

没有魔术\n\n\r总是表示只有一个字符,并且在所有基于ASCII的平台上分别为\cJ\cM。 (唯一的例外是EBCDIC平台(原因很明显)和经典MacOS(其中\n\r都意味着\cM)。)

,在Windows上发生神奇的是,通过标记为一个文件句柄做I/O时,处于文本模式时,\r\n在读取时被翻译为\n,反之亦然。 (另外,\cZ意味着文件结束 - 意外!)这是在C运行时库层完成的。

您需要binmode您的套接字来解决这个问题。

你也应该从你的模式中删除/s/m修饰符:既然你不使用的元字符,其行为他们修改(.和,分别为^/$对),他们做什么 - 货物邪教。