Perl的/ m正则表达式修饰符在Windows上的匹配方式不同吗?

时间:2008-10-18 03:47:36

标签: windows regex perl multiline

以下Perl语句在Unixish机器上的行为相同。他们在Windows上的表现有所不同吗?如果是,是因为魔术\ n?

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

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

3 个答案:

答案 0 :(得分:12)

对于这些正则表达式:

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

/ m和/ s都没有意义。

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

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

那么,该怎么办?我建议将\015个字符设为可选,并将其与

分开
/\015?\012/

不需要/ m,/ s甚至是领先的m//。那些只是货物崇拜。

答案 1 :(得分:3)

没有魔法\n\n\r始终只是一个字符,并且分别位于\cJ\cM的所有基于ASCII的平台上。 (例外情况是EBCDIC平台(出于显而易见的原因)和MacOS Classic(其中\n\r都表示\cM)。)

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

你需要binmode你的套接字来修复它。

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

答案 2 :(得分:1)

为什么要添加/m?你想分手吗?要使用/m执行此操作,您需要在正则表达式中使用^$

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

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

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