6

我用正则表达式编写了一个小的 Perl 脚本来获取网站的 HTML 组件。

我知道这不是做这种工作的好方法,但我试图测试我的正则表达式技能。

当在 while 循环中使用两种正则表达式模式之一运行时,它会完美运行并显示正确的输出。但是当我尝试在 while 循环中检查两种模式时,第二个模式每次都匹配并且循环无限运行。

我的脚本:

#!/usr/bin/perl -w
use strict;

while (<STDIN>) {

    while ( (m/<span class=\"itempp\">([^<]+)+?<\/span>/g) ||
            (m/<font size=\"-1\">([^<]+)+?<\/font>/g) ) {
        print "$1\n";
    }
}

我正在使用示例输入测试上述脚本:

<a href="http://linkTest">Link title</a>
<span class="itempp">$150</span>
<font size="-1"> (Location)</font>

期望的输出:

$150
(Location)

谢谢!任何帮助将不胜感激!

4

3 回答 3

9

每当全局正则表达式无法匹配时,它都会重置下一个全局正则表达式开始搜索的位置。因此,当您的两个模式中的第一个失败时,它会迫使第二个再次从字符串的开头查找。

可以通过添加/c修饰符禁用此行为,如果正则表达式匹配失败,该修饰符会保持位置不变。

此外,您可以通过删除转义字符("不需要转义,/如果您选择不同的分隔符也不需要转义)和+?捕获后多余的字符来改进您的模式。

use warnings-w命令行好得多。

这是您的代码的工作版本。

use strict;
use warnings;

while (<STDIN>) {

    while( m|<span class="itempp">([^<]+)</span>|gc
            or m|<font size="-1">([^<]+)</font>|gc ) {
        print "$1\n";
    }
}
于 2012-07-29T08:40:06.867 回答
3
while (<DATA>) {
    if (m{<(?:span class="itempp"|font size="-1")>\s*([^<]+)}i) {
        print "$1\n";
    }
}

__DATA__
<a href="http://linkTest">Link title</a>
<span class="itempp">$150</span>
<font size="-1"> (Location)</font>
于 2012-07-29T08:21:12.680 回答
-3

您在匹配之后或期间没有更改$_,因此它将始终匹配并进入无限循环。

要修复它,您可以添加$_=$';after print,以在字符串的其余部分再次运行 match。

于 2012-07-29T08:07:55.113 回答