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

hi,

can any one explain me what the following code do.

($whole,$deci) = /(?:(\d*)\.?(\d+))|(?:(\d+)\.?(\d*))/;
thanks in advance

Replies are listed 'Best First'.
Re: meaning for the code
by jwkrahn (Abbot) on Mar 12, 2008 at 08:52 UTC
    can any one explain me what the following code do.    ($whole,$deci) = /(?:(\d*)\.?(\d+))|(?:(\d+)\.?(\d*))/;

    Yes.    The pattern matches either (\d*)\.?(\d+) or (\d+)\.?(\d*).    The variable $whole is assigned the contents of the first set of capturing parentheses ((\d*) or (\d+)) and the variable $deci is assigned the contents of the second set of capturing parentheses ((\d+) or (\d*)).

    Update: Thanks ikegami.    It looks like I couldn't get anything right yesterday.    :-(

      No way!

      The variable $whole is assigned the contents of the first set of capturing parentheses (the first (\d*)).
      The variable $deci is assigned the contents of the second set of capturing parentheses (the first (\d+)).

      /(?:(\d*)\.?(\d+))|(?:(\d+)\.?(\d*))/ ^^^^^ ^^^^^ Always Always $whole $deci

      Should the second alternation match — it never will — then $whole and $deci will be undef.

Re: meaning for the code
by Pancho (Pilgrim) on Mar 12, 2008 at 12:58 UTC

    Also the two ?: symbols at the beginning of the sets of parens make the parens non-capturing, in other words whatever is matched within the parens is not stored as a variable... BUT the parens within those parens that don't start with ?: will capture whats matched in a variable... If you like to tinker with things take the symbols out and see what happens...
    ($whole,$deci) = /(?:(\d*)\.?(\d+))|(?:(\d+)\.?(\d*))/;
    Pancho
Re: meaning for the code
by NetWallah (Canon) on Mar 12, 2008 at 16:22 UTC
    In plain English, here is what the code tries to do:

    Examine the value of $_
    Check if it contains a decimal number, or an integer
    If it does, assign those values to $whole and $deci

    The expression used does handle boundary conditions, which is what make it appear complex.

    It accurately evaluates numbers like 324 44.55 44. .44 and 0.445

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: meaning for the code
by Anonymous Monk on Mar 12, 2008 at 16:48 UTC
    Why not try it and see?

    >perl -wMstrict -e "for (@ARGV) { my ($whole,$deci) = /(?:(\d*)\.?(\d+))|(?:(\d+)\.?(\d*))/; print qq({$_} {$whole} {$deci} \n) } " 0.0 0. 0 . X .0 1.2 1. 1 .2 {0.0} {0} {0} {0.} {} {0} {0} {} {0} Uninitialized value in concatenation (.) or string at -e line 1. Uninitialized value in concatenation (.) or string at -e line 1. {.} {} {} Uninitialized value in concatenation (.) or string at -e line 1. Uninitialized value in concatenation (.) or string at -e line 1. {X} {} {} {.0} {} {0} {1.2} {1} {2} {1.} {} {1} {1} {} {1} {.2} {} {2}

    (Uninitialized value messages truncated to avoid line wrap.)

Re: meaning for the code
by ikegami (Patriarch) on Mar 12, 2008 at 17:15 UTC

    What it does and what it's suppose to do are two separate things.

    /(?:(\d*)\.?(\d+))|(?:(\d+)\.?(\d*))/
    is equivalent to
    /(?:(\d*)\.?(\d+))/
    except the former returns 4 values instead of 2 in list context (the last two being undef).

    Try matching against "123." to illustrate the bug.