Perl模式匹配变量问题

时间:2011-01-05 21:08:41

标签: regex perl backreference

我正在尝试打开文件,匹配特定行,然后围绕该行包装HTML标记。看起来非常简单,但显然我遗漏了一些东西,并且不能正确理解Perl匹配的模式变量。

我将这一行与此相匹配:

$line =~ m/(Number of items:.*)/i;

将整条线放入1美元。我尝试打印出我的新行:

print "<p>" . $1 . "<\/p>;

我希望它打印出来:

<p>Number of items: 22</p>

然而,我实际上得到了这个:

</p>umber of items: 22

我尝试了各种各样的变化 - 在一个单独的行上打印每个位,使用$ +和$&amp;等将$ 1设置为一个新变量,我总是得到相同的结果。

我错过了什么?

3 个答案:

答案 0 :(得分:9)

你的比赛中有一个\ r \ n,在打印时会导致输出格式不正确。

修改 为了进一步解释,您的文件可能有窗口样式\ r \ n行结尾。 chomp 不会删除\ r \ n,然后它会进入你的贪婪匹配,并导致令人不快的输出(\ r \ n意味着返回到行的开头并继续打印)。< / p>

您可以通过添加类似

的内容来删除\ r \ n
$line =~ tr/\015//d;

答案 1 :(得分:3)

您能提供一个完整的代码片段来演示您的问题吗?我没有看到它。

需谨慎的是,1美元和朋友在该动态范围内引用上次成功匹配中的捕获。在使用之前,您应始终验证匹配是否成功:

$line = "Foo Number of items: 97\n";
if ( $line =~ m/(Number of items:.*)/i ) {
    print "<p>" . $1 . "<\/p>\n";
}

答案 2 :(得分:3)

您刚学会(以供将来参考).*可能有多危险。

我的头撞了类似的不愉快,这些天我喜欢尽可能准确地说明我期望抓住的东西。也许

$line =~ m/(Number of items:\s+\d+)/;

然后我肯定不会首先捕获有问题的控制角色。无论Cygwin如何处理Windows文件,我都可以保持无知。