Regex 区分一行中的多个正则表达式命中?

Regex 区分一行中的多个正则表达式命中?,regex,perl,Regex,Perl,我试图用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.$rand

我试图用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";`
}
while(我的$line=){
$line=~$regex{'ipAddress'};
我的$rand0=int(rand(256));
我的$rand1=int(rand(256));
我的$rand2=int(rand(256));
我的$rand3=int(rand(256));
$&=“$rand0.$rand1.$rand2.$rand3\n”`
}
问题是在某些情况下,一行中有多个IP地址。
如何避免它们都得到相同的随机数?

这可能会有帮助:

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);
sub-rip{return join(“.”),map{int(rand(256))}(1..4))}

打开我的$f,首先,
$&
是只读的,您不能这样分配它来修改目标字符串

我也不确定散列的密钥是否真的是
ipadress
(使用一个
d
),但我相信如果不是,您可以修复它

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

while (my $line = <$fh>) {
  $line =~ s{$regex{ipadress}}{
    join '.', map int(rand(256)), 0..3
  }eg;
  print $line;
}
while(我的$line=){
$line=~s{$regex{ipAddress}{
连接“”,映射int(rand(256)),0..3
}eg;
打印$行;
}

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

如果是后者:连续两次调用
rand(256)
得到相同结果的概率是232分之一,这似乎不值得担心,但如果需要保证它们不同,可以保留已选择地址的散列,并在每次生成新地址时进行更新。从@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);

在那里,我想用
$&
任务替换是我错过的一些新功能@Qtax:恐怕没有。关于使用
$&
的警告仍然存在。您可以使用
substr
作为左值,分配给
$&
将与分配给
substr($line,$-[0],$+[0]--[0])
相同。您必须调用“perl-i”才能进行内联编辑,不是吗?
open my $f, '<', 'input' or die($!);
my %picked_addrs;
while (my $line = <$f>){
    $line =~ s/$regex{'ipadress'}/rip(\%picked_addrs)/eg;
}
close($f);