Canonicalizing a large set of addresses using many regex substitutions
Nested loops can be problematic, but you can build regex which can be applied once instead of running foreach

my %replace = (
  str =&gt; { re =&gt; '\bstr\b', output =&gt; "street" },
  rd  =&gt; { re =&gt; '\brd\b', output =&gt; "road" },
);
my ($reCombined) = map qr/($_)/, join "|", map $_-&gt;{re}, values %replace;


and later inside while loop,

# my $string = "Foo str bar rd foo";
$string =~ s/$reCombined/$replace{$1}{output}/g;