in reply to replace all numerics to words in a txt file

hello imhacked and welcome to the monastery and to the wonderful world of Perl!

choroba gave you the solution: but why use isdigit when you can already match directly digits with \d classe in regexes?

I gave a try to this never used by me module ending with the below oneliner: For sure is not the best thing ever seen ( PS indeed! see tremendously wise AnomalousMonk below) but you can play with it (be aware of the win32 double quotes!):

echo 1st rule: 2nd, 3rd and 4th floor must be free in 5 min. Not in 6. + Call 911 for emergencies | perl -MLingua::EN::Numbers="num2en,num2en_ordinal" -pne "s/(\d+)([st|n +d|rd|th])+/num2en_ordinal($1)/ge;s/(\d+)/num2en($1)/ge" first rule: second, third and fourth floor must be free in five min. N +ot in six. Call nine hundred and eleven for emergencies

You can use MO=Deparse to see the above a bit expanded:

perl -MO=Deparse -pne "s/(\d+)([st|nd|rd|th])+/num2en_ordinal($1)/ge; +s/(\d+)/num2en($1)/ge" LINE: while (defined($_ = <ARGV>)) { s/(\d+)([st|nd|rd|th])+/num2en_ordinal($1);/eg; s/(\d+)/num2en($1);/eg; } continue { die "-p destination: $!\n" unless print $_; } -e syntax OK

PPS maybe this is better regex (i'm so rusty..), the char class [..] was totally misplaced, but being all look around assertions zero width ones ( $& not filled ) a simple capturing group seems to work:

s/(\d+)(st|nd|rd|th)/num2en_ordinal($1)/ge

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re^2: replace all numerics to words in a txt file -- oneliner
by AnomalousMonk (Archbishop) on Sep 22, 2017 at 11:09 UTC
    s/(\d+)([st|nd|rd|th])+/num2en_ordinal($1)/ge;

    The  | ordered alternation metacharacter is not meta in a character class. The character class [st|nd|rd|th] is equivalent to [stndrh|] (update: because repeated characters have no special significance in a class). The quantified capture group ([st|nd|rd|th])+ matches any of the characters in the [stndrh|] class one or more times and captures the last such character matched. Try matching against  '2ds' '33hn' '123|s' and a few other such strings. You may want something like the true alternation (?:st|nd|rd|th) possibly supported by some look-around assertions.

    c:\@Work\Perl\monks>perl -wMstrict -le "my $s = '1ds rule: 22hn, 3rd and 123|sdnfloor'; ;; printf qq{'$&' } while $s =~ m{(\d+)([st|nd|rd|th])+}xmsg; " '1ds' '22hn' '3rd' '123|sdn'

    Update: Maybe something like this:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $rx_ordinal_indicator = qr{ (?<! [[:alpha:]]) (?: st | nd | rd | th) (?! [[:alpha:]]) }xms; ;; my $s = '1ds rule: 22hn, 2 then 3rd and 44 th, 2 nd of the 123|sdnfl +oor'; ;; printf qq{'$&' } while $s =~ m{ (\d+) \s* $rx_ordinal_indicator }xms +g; " '3rd' '44 th' '2 nd'
    (Ordinarily, I wouldn't use  $& and friends, but it's convenient for this example.)


    Give a man a fish:  <%-{-{-{-<