Perl RegEx和促销价

时间:2011-08-21 20:15:09

标签: regex perl

我借了the script used by SteamCalculator.com并想稍微修改一下,不仅要抓住Steam上游戏的价格,还要抓住销售价格(如果存在的话)

代码非常简单,易于阅读。要检索价格,他会查看steampowered.com搜索功能中的HTML,将<div class=\"col search_price\"></div>之间的所有内容抽出,然后运行以下子例程:

sub formPrice($)
{
    my $price = shift;

    if($price =~ m/(\d+)(?:\.|,)(\d{2})/)
    {
        return $1.$2;
    }
    else
    {
        return 0;
    }
}

价格可以采用4种形式中的一种,具体取决于您要查找价格的国家/地区代码以及游戏是否在售。这四种形式是:

$9.99
<span><strike>$9.99</strike></span><br>$8.99
9,99£
<span><strike>9.99£</strike></span><br>8,99£

正如您所看到的,无论价格采用何种形式,他的脚本都将获取(\d+)的第一个实例(第一组数字,在每种情况下返回9)以及{ {1}}({1}}之后的{1}}组(点或逗号)。当这些组合在一起时,子程序总是返回(\d{2}),无论价格有四种格式中的哪一种。

我一直试图找到一种方法来修改这个子例程,在案例1和案例3中返回\.|,,但在案例2和案例4中返回999。到目前为止,我尝试过:

1:

999

2:

899

3:

if((reverse $price) =~ m/(\d+)(?:\.|,)(\d{2})/g){
    return $2.$1;
}

首先返回的价格为if($price =~ m/.*?(\d+)(?:\.|,)(\d{2})/g){ return $1.$2; } if($price =~ m/.*?(\d+)(?:\.|,)(\d{2})$/){ return $1.$2; } 。第二个9199仍然是贪婪的,它正在为$19.99返回.*?。在案例3和案例4(处理欧元)中,第三个返回999

3 个答案:

答案 0 :(得分:2)

Flimzy建议最终解决这个问题。

我很好奇你第二次尝试要完成的事情:

if($price =~ m/.*?(\d+)(?:\.|,)(\d{2})/g){
    return $1.$2;
}

在这种情况下,添加g并没有做任何特别有用的事情。将.*(不是.*?)添加到开头可以获得最后一个匹配而不是第一个匹配,但是您需要在比您想要的更晚的时间内防止匹配,例如:

if ( $price =~ m/.*\b(\d+)(?:\.|,)(\d{2})/ ) {
    return $1.$2;
}

答案 1 :(得分:0)

这似乎对我有用:

m/(\d+)(?:\.|,)(\d{2})£?\s*$/

答案 2 :(得分:0)

以下是使用全局选项的方法:

sub price {
    my $str = shift;
    my @nums = $str =~ /(\d+)[.,]*(\d{2})/g;
    return 0 unless @nums;
    return (join '', @nums[-2,-1]);
}

全局/g返回列表中的所有匹配项。如果没有找到匹配,则子返回0,否则返回最后两个,加入一个字符串。使用[.,]*代替前瞻。

更新(根据评论):

稍微快一点的解决方案:从字符串的末尾读取,并直接使用字符串而不是复制。

sub price {
    return (join '', $_[0] =~ /(\d+)[.,](\d{2})\D*$/);
}