Perl在替代本身中进行替代

时间:2019-11-02 23:59:38

标签: regex perl

我正在使用Perl对html代码段进行一些正则表达式替换操作。

这就是我匹配所需部分的方式:(class="p_hw"><a href=")(http://[^<>"]*?xxxx\.com\/[^<>"]*[=/])([^<>"]*)(">(?:<b>)?)(.*?)(?=<)

如果哈希({{1}中存在该值,则我需要用http://替换entry://,然后替换http url($3的某个参数值) }),否则%hw_f中的第一个单词(或短语)将被使用。如果不符合所有条件,则该代码段将保持不变。

我尝试了以下方法:

$5
  

%hw_f是匹配所有条件的地方。

它出现以下错误:

  

在串联(。)或字符串中使用未初始化的值$ 1

我需要在替换内基于s#(class="p_hw"><a href=")(http://[^<>"]*?xxxx\.com\/[^<>"]*[=/])([^<>"]*)(">(?:<b>)?)(.*?)(?=<)# my @n = split(/\,|;/, $5); my @m = map {s,^\s+|\s+$,,mgr} @n; my $new = $3 =~ s/^\s+|\s+$//mgr; my $new2 = $new =~ s/\+/ /mgr; exists $hw_f{$new2} ? "$1entry://$new2$4$5" : (exists $hw_f{$m[0]} ? "$1entry://$m[0]$4$5" : "$1$2$3$4$5") #eg; 获得一个新值,然后继续该新值。我该怎么办?

3 个答案:

答案 0 :(得分:3)

我不会尝试真正地解决您要完成的任务的逻辑,因为建议这样做的确不正确。我要做的是提供一些语义和编码建议。

1:使用Regexp :: Common和URI处理URL。编写自己的正则表达式几乎是不值得的。使用正则表达式解析HTML要求您认真了解自己在做什么。 https://metacpan.org/search?q=regexp%3A%3Acommon

2:始终仅使用{}和//来包装正则表达式。 (99%的规则)

3:除非表达式很简单,否则始终立即将编号的变量复制到有意义的命名my()变量中。

4:使用后缀foreach修改数组。

5:扩展代码格式,使其外观更具吸引力。

6:将sprintf用于复杂的变量重组。这样一来,就可以更轻松地了解在何处以及何处使用了什么变量。

HTH

#  1                        2                                     3        4           5
s{(class="p_hw"><a href=\")(http://[^<>"]*?xxxx\.com/[^<>"]*[=/])([^<>\"]*)(\">(?:<b>)?)(.*?)(?=<)}{
    my ($m1, $m2, $m3, $m4, $m5) = ($1, $2, $3, $4, $5);
    my @n = split /[,|;]/, $m5;
    s/^\s+|\s+$//mg foreach @n;
    (my $new = $m3) =~ s/^\s+|\s+$//mg;
    (my $new2 = $new) =~ s/\+/ /g;
    exists $hw_f{$new2} ?
        sprintf "%sentry://%s%s%s", $m1, $new2, $m4, $m5 :
        exists $hw_f{$n[0]} ? 
        sprintf "%sentry://%s%s%s", $m1, $n[0], $m4, $m5 :
        "$m1$m2$m3$m4$m5";
}ige;

答案 1 :(得分:1)

更新:

while (<DICT>) {
s#(class="p_hw"><a href=")(http://[^<>"]*?wordinfo\.info\/[^<>"]*[=/])([^<>"]*)(">(?:<b>)?)(.*?)(?=<)#
        my $one = $1;
    my $two = $2;
    my $three = $3;
    my $four = $4;
    my $five = $5;
        my @n = split(/\,|;/, $5);
    my @m = map {s,^\s+|\s+$,,mgr} @n;
    my $new = $3 =~ s/^\s+|\s+$//mgr;
    my $new2 = $new =~ s/\+/ /mgr;
    exists $hw_f{$new2} ? $one."entry://$new2$four$five" : (exists $hw_f{$m[0]} ? $one."entry://$m[0]$four$five" : "$one$two$three$four$five") #eg;

    print $FH $_;
}

在所有正则表达式引擎调用之前,将所有捕获变量分配为@DavidO(在上述注释中),它终于可以工作了。谢谢。

答案 2 :(得分:0)

根据您的帖子,您尝试实现的目标并不明显。如果您以以下格式描述问题,则会更容易理解

---示例-----------------------

我从网页中提取了一个带有<a href="http:\\.......的代码段,我希望将其转换/转换为以下格式<a href="http:\\.......

至少以这种方式,我们知道什么是 INPUT 和什么 OUTPUT

---示例结尾------------

当您将正则表达式与内存一起应用时,将记住的值存储在数组中或更好的哈希值中更容易

use strict;
use warnings;

use Data::Dumper;

my %href;

$data = shift;

if( $data =~ /<a href="(\w+):\\\\([\w\d\.]+)\\([\w\d\.]+)\\(.+)">([^<]+)</ ) {
    @href{qw(protocol dns dir rest desc)} = ($1,$2,$3,$4,$5);
    print Dumper(\%href);
} else {
    print "No match found\n";
}