我用正则表达式编写了一个小的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)
谢谢!任何帮助将非常感谢!
答案 0 :(得分:9)
每当全局正则表达式无法匹配时,它将重置下一个全局正则表达式将开始搜索的位置。因此,当您的两个模式中的第一个失败时,它会强制第二个模式再次从字符串的开头看。
可以通过添加/c
修饰符来禁用此行为,如果正则表达式无法匹配,则会保持位置不变。
此外,您可以通过删除转义字符来改进您的模式("
不需要转义,如果您选择不同的分隔符,则/
无需转义)和多余+?
1}}捕获之后。
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";
}
}
答案 1 :(得分: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>
答案 2 :(得分:-3)
在匹配之后或匹配期间,您没有更改$_
,因此它将始终匹配并进入无限循环。
要修复它,您可以在$_=$';
之后添加print
,以便在字符串的其余部分再次运行匹配。