multiple text replacements from a hash

Discussion in 'Perl Misc' started by George Mpouras, Apr 1, 2013.

  1. Hello,

    I have a hash holding "from" - "to" text pieces.
    I want to replace on a given text all the "from" parts with the "to".
    The following piece of code is working, but I know it is doing not necessary
    loops, can you help me to do it better ;



    use strict;
    use warnings;
    use feature qw/say/;

    my $text = '172.16.0.36 customer1.com company.comcompany.com erw
    172.16.0.36customer1.com';

    my %Replace = (
    '10.1.1.21' => '192.168.0.9',
    '255.255.0.0' => '255.255.255.0',
    'customer1.com' => 'local.lan',
    '172.16.0.1' => '192.168.0.1',
    'company.com' => 'local.lan',
    '10.1.31.100' => '192.168.0.7',
    '172.16.0.36' => '192.168.0.7',
    '10.1.18.105' => '192.168.0.1',
    '255.255.240.0' => '255.255.255.0',
    '172.16.0.2' => '192.168.0.9');





    # We find the min and max hash lengths to avoid later as many iterations is
    possible
    my $Min_length;
    my $Max_length = 0;
    foreach my $property (keys %Replace) {
    $Max_length = length $Replace{$property} if length $Replace{$property} >
    $Max_length;
    $Min_length //= $Max_length;
    $Min_length = length $Replace{$property} if length $Replace{$property} <
    $Min_length;
    }



    my $offset = 0;
    while ( $offset < length $text) {
    my $offset_walk = 0;
    #say "*$offset* $text";

    for (my $i = $Max_length; $i >= $Min_length; $i--) {
    my $piece = substr($text, $offset, $i);

    if ( exists $Replace{$piece} ) {
    substr($text, $offset, $i, $Replace{$piece});
    $offset_walk = length $Replace{$piece};
    last
    }
    }

    $offset += $offset_walk == 0 ? 1 : $offset_walk;
    }


    say $text;
     
    George Mpouras, Apr 1, 2013
    #1
    1. Advertising

  2. "George Mpouras"
    <>
    writes:

    > I have a hash holding "from" - "to" text pieces.
    > I want to replace on a given text all the "from" parts with the
    > "to".
    >
    > my $text = '172.16.0.36 customer1.com company.comcompany.com
    > erw 172.16.0.36customer1.com';
    >
    > my %Replace = (
    > '10.1.1.21' => '192.168.0.9',
    > '255.255.0.0' => '255.255.255.0',
    > 'customer1.com' => 'local.lan',
    > '172.16.0.1' => '192.168.0.1',
    > 'company.com' => 'local.lan',
    > '10.1.31.100' => '192.168.0.7',
    > '172.16.0.36' => '192.168.0.7',
    > '10.1.18.105' => '192.168.0.1',
    > '255.255.240.0' => '255.255.255.0',
    > '172.16.0.2' => '192.168.0.9');


    Considering that none of your keys is a prefix of another key, the
    obvious idea would be to collect them all into a regex:

    my $re = join('|', map { quotemeta($_) } keys(%Replace));
    $re = qr/($re)/;

    and do all replacements with the single s/// statement

    $text =~ s/$re/$Replace{$+}/g;

    If you had keys which are prefixes of other key, you could use

    my $re = join('|', map { quotemeta($_) } sort { $b cmp $a } keys(%Replace));

    to prefer the longer match or

    my $re = join('|', map { quotemeta($_) } sort keys(%Replace));

    to prefer the shorter.

    Another good idea might be to use an existing macro (pre-)processor,
    eg, m4, for tasks like this.
     
    Rainer Weikusat, Apr 1, 2013
    #2
    1. Advertising

  3. clever, I have taken a wrong path.
     
    George Mpouras, Apr 1, 2013
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Bengtsson

    Squezing in replacements into strings

    Peter Bengtsson, Apr 25, 2005, in forum: Python
    Replies:
    3
    Views:
    327
    Peter Bengtsson
    Apr 25, 2005
  2. Claude Henchoz

    URL 'special character' replacements

    Claude Henchoz, Jan 9, 2006, in forum: Python
    Replies:
    6
    Views:
    679
    Claude Henchoz
    Jan 9, 2006
  3. Brian McCullough
    Replies:
    0
    Views:
    519
    Brian McCullough
    Feb 16, 2007
  4. rp
    Replies:
    1
    Views:
    594
    red floyd
    Nov 10, 2011
  5. Robert Neville
    Replies:
    4
    Views:
    149
    Mumia W.
    Apr 3, 2007
Loading...

Share This Page