http://qs1969.pair.com?node_id=11129291


in reply to Combining multiple =~ s/

Let Perl generate the regular expression from a hash containing the list of words and their replacements:
my %trans = (zero => 0, one => 1, two => 2, three => 3); my $words_re = join "|", map quotemeta, keys %trans; $string =~ s/($words_re)/$trans{lc $1}/ig;

Replies are listed 'Best First'.
Re^2: Combining multiple =~ s/
by Corion (Patriarch) on Mar 07, 2021 at 19:10 UTC

    You want to sort the words in the regular expression by descending length :) Or alternatively, use \b to match only whole words:

    my %trans = (zero => 0, one => 1, ones => 11, two => 2, three => 3); my $words_re = join "|", map quotemeta, sort { length($b) <=> length($ +a) } keys %trans; $string =~ s/\b($words_re)\b/$trans{lc $1}/ig;

    Otherwise, it could be that one matches before ones.

    Update: choroba spotted that the length($b) and length($a) were missing

      It might be worth pointing out the CPAN module Data::Munge which has a function list2re to make a list-matching regex. This line is basically what you need:

      my $re = join '|', map quotemeta, sort {length $b <=> length $a || +$a cmp $b } @_;

      There is also this, which is what I use.

Re^2: Combining multiple =~ s/
by LanX (Saint) on Mar 07, 2021 at 20:44 UTC
    Nitpick! :)

    This is semantically not the same, even if sorted.

    Tho probably what the OP wants, if it's really about numbers

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery