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

I'm using such an excellent reference right now, that even the book samples dont work. All pun intended

Referring to and it says this:

"The x option tells the Perl interpreter to ignore all white space unless preceded by a backslash. As with the pattern-matching operator, ignoring white space makes complicated string patterns easier to read.

$string =~ s/\d{2} ([\W]) \d{2} \1 \d{2}/$1-$2-$3/x

This converts a day-month-year string to the dd-mm-yy format.

Now the question is this: These special built in variables namely $1, $2 that store the value of pattersn in parentheses SHOULD in theory match the pattern

([\W])

So obviously, $1,$2,$3 contain just the value "/", so how is this string substitution to work?

For all purposes (as I understand it) THIS should work: $string =~ s/(\W)/-/x;

Am I missing something here?

Thanks.

Edited by castaway - added code tags.

Replies are listed 'Best First'.
Re: String Substitution Operator
by TheHobbit (Pilgrim) on Oct 23, 2003 at 09:10 UTC

    Hi,
    I'd realy like to know what this reference is... People that write that sort of things should be hung and sent to the programmers' hell, where they'll have to write useless software in VB for the eternity... (I'm doing right this now, writing useless software in VB I mean, and I can not immagine a better definition of programmers' hell).

    Obviously,

    $string =~ s/\d{2} (\W) \d{2} \1 \d{2}/$1-$2-$3/x

    does not what that wanna be reference says. Infact, it also is semanticaly wrong, $2 and $3 being undefined in the replacement part: the matching part of the s/// operator contains only one pair of parenthesis, so that only $1 is defined.

    The sobstitution you propose almost does the work. I say almost because:

    1. it replaces only the first not-word character it founds in $string: use the /g option to solve this problem
    2. it replaces any not-word character, not just slashes.

    a third problem (that could be disregarded) is that the /x option is useless, since there are nor spaces nor comments in the regex.

    A simpler way to to that would be to use the tr/// operator, like in

    $string =~ tr!/!-!;

    Obvously, all this still lets you short of an useful example about how and why use the /x option in matching operators. I'm sorry, but I have none to offer to you now, may be later, when I'll be at home with all my little files at hand...

    Hoping that this helps...


    Leo TheHobbit
Re: String Substitution Operator
by davido (Cardinal) on Oct 23, 2003 at 08:23 UTC
    I'm not sure if I completely understand your question, partially because the regexps are obscured since code tags weren't used to preserve things like []. And partially because the text that came between "Now the question is this:" and the question mark, didn't really make sense to me.

    From what I can tell, it looks to me like in the first regexp, you're only capturing with one set of parens. That means that $1 is the only variable that will have anything captured into it, in your first regexp. Nothing is populating $2 and $3. Also, $1 will only have something captured into it if the overall match was a success. Also, there is no need to use square brackets around \W if you're only matching one character, with a built-in character class. The square brackets are generally used to create custom character classes.

    I hope this is of some help.

    If your book gave you the regexp you have shown us, it would be a good candidate for the garbage heap. You might really get a lot out of perlretut, followed by perlfaq6, followed by perlre. Those three online POD's give a very thorough explanation of regular expressions, and start out (in perlretut) at a pace that isn't too overwhelming.

    As far as what $1 $2 and $3 would "obviously" contain, I have no idea because you didn't provide the actual input string for us to see.

    Your second regexp (the one that follows "THIS should work:" will substitute the first non-word character in the string with a hyphen. Is that what you meant by "work"? I might be missing something too. ;)


    Dave


    "If I had my life to do over again, I'd be a plumber." -- Albert Einstein

      How do I :

      convert a string in day-month-year format to the dd-mm-yy format?

      I use :$string =~ s/(\W)/-/x;

      But the book asks me to use: $string =~ s/\d{2} ([\W]) \d{2} \1 \d{2}/$1-$2-$3/x instead and hence the confusion, since the special variables $1 etc will just match the pattern in parentheses, does this not mean that $1,$2,$3 should just contain the hyphen and NOT the *day*,*month*,*year* values?

      A related question is: if I do want to use the day,month,year values, how do I do that?

      Thanks.
        If I provide a string like "14/01/52", I want the output to be : "14-01-52".