区分正则表达式中的多个正则表达式?

问题描述:

我想在Perl更换IP-地址与随机数:区分正则表达式中的多个正则表达式?

while (my $line = <file>){ 
    $line =~ $regex{'ipadress'}; 

    my $rand0 = int(rand(256)); 
    my $rand1 = int(rand(256)); 
    my $rand2 = int(rand(256)); 
    my $rand3 = int(rand(256)); 

    $& = "$rand0.$rand1.$rand2.$rand3\n";` 
} 

的问题是,在某些情况下,有多个IP的地址在同一行。
如何避免他们都得到相同的随机数字?

那么一开始$&是只读的,你不能分配给它这样的修改目标字符串。

我也不确定你的散列键是否真的是ipadress(有一个d),但我相信如果没有的话你可以修复它。

我会写这样的东西。替代运算符上的/e修饰符会导致替换字符串为执行以确定替换匹配的内容。 join语句生成从0到255的四个字节值,并将它们用点连接以形成一个随机地址。

while (my $line = <$fh>) { 
    $line =~ s{$regex{ipadress}}{ 
    join '.', map int(rand(256)), 0..3 
    }eg; 
    print $line; 
} 
+1

在那里我想*替换为'$&'赋值*是我错过的一些新功能。 ;-) – Qtax

+0

@Qtax:不,我恐怕不是。有关使用'$&'*的警告依然存在。你可以使用'substr'作为一个左值,而赋值给'$&'与分配给substr($ line,$ - [0],$ + [0] - $ - [0])是一样的。 )'。 – Borodin

这可能会有所帮助:

sub rip { return join(".", map { int(rand(256)) } (1..4)) } 

open my $f, '<', 'input' or die($!); 
while (my $line = <$f>){ 
    $line =~ s/$regex{'ipadress'}/rip()/eg; 
} 
close($f); 
+0

你必须调用“perl -i”才能够内联编辑,不是吗? – hcrudolph

这些答案是确保为每个IP地址选择新随机数的好方法。但海报的主要问题是,“如何避免它们都得到相同的随机数?”并且我不清楚他们是否意味着“为每个IP地址获得四个随机数字”或“保证没有两个随机选择的IP地址是相同的。”

如果是后者:让从rand(256)四次调用了同样的结果连续两次的概率是一个在2 ,这似乎根本不值得担心,但如果你需要保证他们不同的是,你可以保留你已经选择的地址的哈希值,并在每次生成新地址时更新它。从@ perreal的解决方案偷:

sub rip { 
    my $picked_addrs = shift; 
    my $new_addr; 
    do { 
     $new_addr = join(".", map { int(rand(256)) } (1..4)); 
    } while defined($picked_addrs->{$new_addr}); 
    $picked_addrs->{$new_addr} = 1; 
    return $new_addr; 
} 

open my $f, '<', 'input' or die($!); 
while (my $line = <$f>){ 
    my %picked_addrs; 
    $line =~ s/$regex{'ipadress'}/rip(\%picked_addrs)/eg; 
} 
close($f); 

如果你想确保你永远不会选择同一地址的文件中的任何地方两次,只是声明%picked_addrswhile外循环,所以它不会重置每行:

open my $f, '<', 'input' or die($!); 
my %picked_addrs; 
while (my $line = <$f>){ 
    $line =~ s/$regex{'ipadress'}/rip(\%picked_addrs)/eg; 
} 
close($f);