Html 使用一对Perl正则表达式匹配的无限循环

Html 使用一对Perl正则表达式匹配的无限循环,html,regex,string,perl,pattern-matching,Html,Regex,String,Perl,Pattern Matching,我编写了一个带有正则表达式的小Perl脚本来获取网站的HTML组件 我知道这不是做这种工作的好方法,但我试着测试一下我的正则表达式技能 当在while循环中使用两个正则表达式模式中的任意一个运行时,它会完美地运行并显示正确的输出。但是当我尝试检查while循环中的两个模式时,第二个模式每次都匹配,循环无限运行 我的剧本: #!/usr/bin/perl -w use strict; while (<STDIN>) { while ( (m/<span class=\

我编写了一个带有正则表达式的小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";
    }
}

谢谢大家!!任何帮助都将不胜感激

在匹配之后或匹配过程中,您没有更改
$\uu
,因此它将始终匹配并运行到无限循环中

要修复它,您可以添加
$\uU9=$
打印后,在字符串的其余部分再次运行匹配。

while(){
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>

如果(m{\s*([^每当一个全局正则表达式无法匹配时,它都会重置下一个全局正则表达式开始搜索的位置。因此,当两个模式中的第一个模式失败时,它会强制第二个从字符串的开始处再次查找

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

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

而且
使用警告
比命令行上的
-w
好得多

这是您的代码的工作版本

use strict;
use warnings;

while (<STDIN>) {

    while( m|<span class="itempp">([^<]+)</span>|gc
            or m|<font size="-1">([^<]+)</font>|gc ) {
        print "$1\n";
    }
}
使用严格;
使用警告;
而(){

而(m)|([^因为分配给
$\uuuuuz
是个坏主意。尤其是在没有必要的情况下。除非您确实知道自己在做什么以及为什么需要它,否则应该避免这种肮脏的把戏。我投了反对票,因为这是错误的。标量上下文中的全局正则表达式匹配将在没有任何帮助的情况下从上一次成功匹配后搜索,并且我由于不同的原因,t在这里失败。通常也不应该使用
$”
变量。正如文档所述,在程序中的任何位置使用此变量都会对所有正则表达式匹配造成相当大的性能损失。额外的捕获,或
substr$,$+[0]
更好。如果要处理多行代码,则必须采用不同的方法。当您逐行处理STDIN时,内部代码仍然会变得无用。使用HTML解析器将是最不容易出错的解决方案。您还可以尝试使用触发器操作符
匹配块。
@mugenkenichi:胡说八道。外部
while
迭代文件的行,而内部的则迭代行内模式的出现。为什么内部的
没有用呢?如果你处理多行..我的意思是如果开始标记与结束标记位于不同的行上。无论如何,使用专门的语法分析器。@mugenkenichi:从这个问题上,我知道这不是做这类工作的好方法,但我试着测试我的正则表达式技能。是的。似乎没有正则语言问题来提高正则表达式技能。每个人都必须在非正则语法上尝试正则表达式。现代正则表达式引擎能够处理这些问题,但我几乎做到了对于无法处理非常规语言的正则表达式,总是会遇到这样的问题。“但我只想解析HTML的子集…”、“我想测试我的正则表达式技能…”、“使用解析器太复杂了”"…在经历了一系列错误、失败和极端情况之后,每个人都会爬回真正的解析器。太好了!我对perl一点也不在行。我正在尝试学习perl,因为它很容易处理所有的事情。谢谢你清楚、简洁地解释了答案。在这篇文章中,我一直在尝试学习regex,但即使我知道w一些基本的东西,比如
做什么等等,我不知道如何正确地实现这些。关于它的任何提示?谢谢!是一个有用的源代码。你会在阅读和尝试的过程中熟悉它。我建议使用正则表达式测试工具。支持Perl正则表达式。如果你正在运行Windows,你可能也会喜欢。很抱歉,我不得不更改“corr”ect答案“因为@Borodin为这个问题提供了一个很好的解释。谢谢你的努力。
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>
use strict;
use warnings;

while (<STDIN>) {

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