Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am looking to convert part of a string to lower case, after having matched it. The line I already have is:

$input =~ s/\.(.)\.WI$/\_\1\_w/g;

This is for parsing and changing input of the form:

ABC.A.WI - this is the initial string

ABC_A_w - this is what the above line currently does

ABD_a_w - this is what I want it to do

I was trying to implement the lc command within the replacement but could not get it to work. I also tried to sub in a tr/A-Z/a-z/ but again could not get the notation correct for it to work properly. Hopefully there is some obscure combination of brackets that will allow me to do something like lc(/1). Please help. Thanks, Martin.

Replies are listed 'Best First'.
(jeffa) Re: Converting case in a replacement
by jeffa (Bishop) on Aug 28, 2001 at 23:56 UTC
    Try the \L and \E thingies (i prefer $1 instead of \1 on the 'replace' side - \1 really should be used on the 'match' side):
    s/\.(.)\.WI$/\_\L$1\E\_w/g;
    This produces 'ABC_a_w' - was the 'D' in 'ABD_a_w' a typo? Looks like it is.

    UPDATE: to explain a little bit, \L means 'make the following lower case until \E (end) is found'. Conversely, you can upper case with \U.

    jeffa

        A flute with no holes is not a flute . . .
    a doughnut with no holes is a danish.
                                    - Basho,
                                      famous philosopher
    
      Yeah it was a typo

      Thanks very much for your help!

      I was too busy looking in the books for info on pattern matching and regexp, didnt think to look at escape sequences.

      Thanks again!

Re: Converting case in a replacement
by wog (Curate) on Aug 29, 2001 at 00:07 UTC
    In addition to jeffa's solution, there are (at least) two other ways you can do this task:

    • You can add the /e option to the s/// so you can insert perl code including the lc: $input =~ s/\.(.)\.WI$/'_'.lc($1).'_w'/emg.
    • You can use the \l escape in the string, which means lowercase-next-char: $input =~ s/\.(.)\.WI$/_\l${1}_w/mg.

    You appear to not be using warnings, a good idea. If you were using warnings, you would get the warning, "\1 better written as $1". (Either that, or you're using a very old version of perl -- please upgrade.) </p.

    Also you probably want to add the /m ("multiple lines") option to your regex. As described in perlre, it is required for $ to match any end of line in the string, not just one at the end of string.

Re: lower case converison in pattern match
by VSarkiss (Monsignor) on Aug 29, 2001 at 00:09 UTC

    If you just need to lowercase one letter, this: $input =~ s/\.(.)\.WI$/_\L$1_w/;will do the trick. The \L modifier in the result side renders the next letter in lowercase. It's not that obscure; just look in perlman:perlre.

    If you want to do more fancy processing, you can use the </code>/e</code> modifier. The same page has details.

    HTH

Re: lower case converison in pattern match
by Masem (Monsignor) on Aug 29, 2001 at 00:08 UTC
    You'll want to add the e modifier to the s/// function:
    $input =~ s/(\.)(.)(\.)WI$/'_'.lc($2).'_w'/ge;
    (Note that you need to group and remove the periods as well in this).

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    It's not what you know, but knowing how to find it if you don't know that's important