【问题标题】:regex doesn't match in Perl正则表达式在 Perl 中不匹配
【发布时间】:2016-06-29 15:00:34
【问题描述】:

我将使用此脚本提取一些抓取数据的名称和 ID:

if ( $string =~ m/(;r=\d*.*<)/ ) {

    $mystring = $1;
    $mystring =~ s/;//;

    if ( $mystring =~ m/(>.*<)/ ) {

        $mystring = $1;
        $mystring =~ s/>//;
        $mystring =~ s/<//;

        print "$mystring \n";
    }
}

其中$string 每次迭代包含一行输入文件。以下是几行:

<pre>
<option data-url="/nav/extra/list?s=prix_asc&amp;cat=436&amp;npk=1&amp;b=4294959199&amp;r=4294959195" >ZAN 3713</option>
<option data-url="/nav/extra/list?s=prix_asc&amp;cat=436&amp;npk=1&amp;b=4294959199&amp;r=4294959194" >ZAN2310</option>
<option data-url="/nav/extra/list?s=prix_asc&amp;cat=436&amp;npk=1&amp;b=4294959199&amp;r=4294959193" >ZAN2410</option>

结果我通常期望的是;r=4294959193" &gt;ZAN2410&lt;;但问题是 Perl 没有检测到任何匹配! 我的正则表达式有问题吗?

【问题讨论】:

  • 如果你有一个完整的 HTML 文档,你应该使用 HTML 解析器而不是正则表达式。
  • @simbabque 你说得对,但作为一个问题,我想知道问题出在哪里。
  • 我认为这可能太贪心了,但我得看看你是如何阅读文件的以及$string 包含什么。您可以将use re 'debug' 添加到代码顶部以查看正则表达式引擎在做什么。这可能会给你一个提示。

标签: regex perl pattern-matching


【解决方案1】:

是的,可能有。但老实说,我可能会以不同的方式处理它。使用 HTML 解析器是第一个调用端口。

例如 - 您正在重复使用 $mystring,这通常是一个警告信号,表明您没有使用 strictwarnings,因此正在做您不期望的事情。

你没有得到你想要的输出,因为你用这个位覆盖了$mystring,例如:

    if($mystring =~ m/(>.*<)/){
        $mystring = $1;

但是用你的示例数据运行你的代码 - 它似乎几乎可以工作 - 因为你正在破坏 $mystring 你得到:

ZAN 3713 
ZAN2310 
ZAN2410 

不过,我建议采用稍微不同的方法:

while (<DATA>) {
    m/r=(\d+)\"\s*>([^<]+)/g && print "$1 $2\n";
}

__DATA__
<pre>
<option data-url="/nav/extra/list?s=prix_asc&amp;cat=436&amp;npk=1&amp;b=4294959199&amp;r=4294959195" >ZAN 3713</option>
<option data-url="/nav/extra/list?s=prix_asc&amp;cat=436&amp;npk=1&amp;b=4294959199&amp;r=4294959194" >ZAN2310</option>
<option data-url="/nav/extra/list?s=prix_asc&amp;cat=436&amp;npk=1&amp;b=4294959199&amp;r=4294959193" >ZAN2410</option>

这会给你输出:

4294959195 ZAN 3713
4294959194 ZAN2310
4294959193 ZAN2410

【讨论】:

  • 非常感谢 Sobrique。感谢您的解决方案,我可以解决问题。
【解决方案2】:

您的代码似乎符合您的要求。 (第一个)$mystring 的值评估为

;r=4294959195" >ZAN 3713<
;r=4294959194" >ZAN2310<
;r=4294959193" >ZAN2410<

最后一个匹配你期望的字符串;r=4294959193" &gt;ZAN2410&lt;

然后你继续提取 &gt;&lt; 之间的值并打印它,这给出了

ZAN 3713 
ZAN2310 
ZAN2410 

这又是我所期望的,所以我在这里没有看到任何问题。要获得您说想要的结果,您应该完全省略内部 if

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多