2

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

我将这条线与此匹配:

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

这使整条生产线变成了 1 美元。然后我尝试像这样打印出我的新行:

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

我希望它打印这个:

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

但是,我实际上得到了这个:

</p>umber of items: 22

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

我错过了什么?

4

3 回答 3

9

您的比赛中有一个 \r ,打印时会导致格式错误的输出。

编辑: 为了进一步解释,您的文件可能具有 Windows 样式 \r\n 行尾。chomp不会删除 \r,然后它会陷入你的贪婪匹配中,并导致令人不快的输出(\r 表示返回到行首并继续打印)。

您可以通过添加类似的东西来删除 \r

$line =~ tr/\015//d;
于 2011-01-05T21:19:41.747 回答
3

您刚刚了解到(供将来参考)有多危险.*

在对类似的不愉快进行了猛烈抨击之后,这些天来,我喜欢尽可能精确地描述我期望捕捉的内容。也许

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

然后我肯定不会首先捕获有问题的控制字符。无论 Cygwin 可能对 Windows 文件做什么,我都可以保持无知。

于 2011-01-05T22:31:06.183 回答
3

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

需要注意的一件事是 $1 和朋友指的是该动态范围内最后一次成功匹配的捕获。在使用匹配之前,您应该始终验证匹配是否成功:

$line = "Foo Number of items: 97\n";
if ( $line =~ m/(Number of items:.*)/i ) {
    print "<p>" . $1 . "<\/p>\n";
}
于 2011-01-05T21:15:25.693 回答