Regular Expression Question

Discussion in 'Perl Misc' started by jonasforssell@yahoo.se, May 12, 2007.

  1. Guest

    Hello,


    I have a file like this:

    2 45 3
    3 44 2 65

    In other words, the first number states how many follwing numbers
    there will be.

    ^([0-9]) ([0-9]){$1}$

    The above regexp does not seem to work for parsing this. I guess the
    $1 parameter is not accepted.
    Any ideas of an alternative?

    Thanks
    /Jonas
    , May 12, 2007
    #1
    1. Advertising

  2. On May 12, 1:08 pm, wrote:

    > Subject: Regular Expression Question


    [ snip: question about using a backreference as a repeat count in
    regex ]

    Please put the subject of your post in the Subject of your post.

    If in doubt try this simple test. Imagine you had done a search before
    you posted. Then imagine that your subject line came up in the list of
    hits. Would you have been able to guess with any degree of certainly
    that it was the same question? If the answer is no then your subject
    line is not good enough.

    Remember: Just because you come here to get help not give it you
    should not have the mindset that you are only here to take and have no
    moral duty to give anything back to the community.

    For example when poncenby asked this question on 6th Oct 2006 his
    subject was "backreference oddity"[1]. Still not good but at least it
    mentions that this is a question about backreferences.

    A good subject would have been "Using a backreference as a repeat
    count in regex".

    [1] Looking up this thread to see the answer is left as an exercise
    for the reader.
    Brian McCauley, May 12, 2007
    #2
    1. Advertising

  3. On Sat, 12 May 2007 05:08:02 -0700, jonasforssell wrote:

    > Hello,
    >
    >
    > I have a file like this:
    >
    > 2 45 3
    > 3 44 2 65
    >
    > In other words, the first number states how many follwing numbers there
    > will be.
    >
    > ^([0-9]) ([0-9]){$1}$
    >
    > The above regexp does not seem to work for parsing this. I guess the $1
    > parameter is not accepted.
    > Any ideas of an alternative?


    I think $1 is substituted before matching against the regexp, so you get
    the value that was in $1 before the match. I guess something like the
    following (untested!) should work.

    if (/^(\d+)/) {
    if (/(\d+) (?:(\d+) ?){$1}$/) {
    # we have a match
    }
    }

    HTH,
    M4
    Martijn Lievaart, May 12, 2007
    #3
  4. Mirco Wahab Guest

    wrote:
    > Hello,
    >
    >
    > I have a file like this:
    >
    > 2 45 3
    > 3 44 2 65
    >
    > In other words, the first number states how many follwing numbers
    > there will be.
    >
    > ^([0-9]) ([0-9]){$1}$
    >
    > The above regexp does not seem to work for parsing this. I guess the
    > $1 parameter is not accepted.
    > Any ideas of an alternative?


    You could use dynamic quantifier. I'm not sure,
    one can put \1 directly into a quantifier
    (maybe it works sometimes).

    This works - dynamic quantifier by (??{ ... })

    ...

    print grep /^ # lock to start of line
    (\d+)\s+ # extract quantifier + space
    (??{ "(\\d+\\s+){$1}" }) # construct the (\d+\s+){N} thing
    $ # lock to end of line
    /x, <DATA>;

    ...

    __DATA__
    2 45 3
    3 44 2 65
    5 43 4 43 4444
    1 43 4 43 4444
    3 44 2 65

    Regards

    M.
    Mirco Wahab, May 12, 2007
    #4
  5. wrote:
    >
    > I have a file like this:
    >
    > 2 45 3
    > 3 44 2 65
    >
    > In other words, the first number states how many follwing numbers
    > there will be.
    >
    > ^([0-9]) ([0-9]){$1}$
    >
    > The above regexp does not seem to work for parsing this. I guess the
    > $1 parameter is not accepted.
    > Any ideas of an alternative?


    while ( <FILE> ) {
    my ( $count, @data ) = /\d+/g;
    if ( $count == @data ) {
    print "Yes! we have valid data.\n";
    }
    else {
    warn "Error: expected $count elements but received " . @data . "
    instead.\n";
    }
    }



    John
    --
    Perl isn't a toolbox, but a small machine shop where you can special-order
    certain sorts of tools at low cost and in short order. -- Larry Wall
    John W. Krahn, May 12, 2007
    #5
  6. Mumia W. Guest

    On 05/12/2007 07:08 AM, wrote:
    > Hello,
    >
    >
    > I have a file like this:
    >
    > 2 45 3
    > 3 44 2 65
    >
    > In other words, the first number states how many follwing numbers
    > there will be.
    >
    > ^([0-9]) ([0-9]){$1}$
    >
    > The above regexp does not seem to work for parsing this. I guess the
    > $1 parameter is not accepted.
    > Any ideas of an alternative?
    >
    > Thanks
    > /Jonas
    >


    The task is complicated by the fact that $1 is not valid until the
    regular expression that sets it is finished. Here's one way to do it:

    my $data = q{ 2 45 3 5 6 7 8 };
    # 5 6 7 and 8 should be ignored.

    my @nums = do {
    $data =~ /^ *(\d) ([\d ]+)/
    && ($2 =~ /((?:\d+ +){$1})/)
    && ($1 =~ /\d+/g)
    };
    Mumia W., May 12, 2007
    #6
  7. Mirco Wahab Guest

    John W. Krahn wrote:
    > while ( <FILE> ) {
    > my ( $count, @data ) = /\d+/g;
    > if ( $count == @data ) {
    > print "Yes! we have valid data.\n";
    > }
    > else {
    > warn "Error: expected $count elements but received " . @data . " instead.\n";
    > }
    > }


    Good idea!

    in Perl, your approach would then look like

    my @data = grep $_->[0] == @$_-1, map [split], <FILE>;

    or something, I guess ;-)

    Regards

    M.
    Mirco Wahab, May 12, 2007
    #7
  8. On May 12, 6:43 am, "John W. Krahn" <> wrote:
    > wrote:
    >
    > > I have a file like this:

    >
    > > 2 45 3
    > > 3 44 2 65

    >
    > > In other words, the first number states how many follwing numbers
    > > there will be.

    >
    > > ^([0-9]) ([0-9]){$1}$

    >
    > > The above regexp does not seem to work for parsing this. I guess the
    > > $1 parameter is not accepted.
    > > Any ideas of an alternative?

    >
    > while ( <FILE> ) {
    > my ( $count, @data ) = /\d+/g;
    > if ( $count == @data ) {
    > print "Yes! we have valid data.\n";
    > }
    > else {
    > warn "Error: expected $count elements but received " . @data . "
    > instead.\n";
    > }
    > }
    >


    Or, if backref's weren't required:

    my( $tot, $cnt );
    print "yes..." if $tot = ($cnt,()) = /\d+/g and $tot == $cnt+1;

    --
    Charles DeRykus
    comp.llang.perl.moderated, May 14, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Andrew Munn

    Regular expression question...

    Andrew Munn, Jun 29, 2003, in forum: Perl
    Replies:
    1
    Views:
    2,126
    rakesh sharma
    Jun 30, 2003
  2. Glenn Kidd

    Regular expression question

    Glenn Kidd, Aug 18, 2003, in forum: Perl
    Replies:
    0
    Views:
    931
    Glenn Kidd
    Aug 18, 2003
  3. VSK
    Replies:
    2
    Views:
    2,290
  4. =?iso-8859-1?B?bW9vcJk=?=

    Matching abitrary expression in a regular expression

    =?iso-8859-1?B?bW9vcJk=?=, Dec 1, 2005, in forum: Java
    Replies:
    8
    Views:
    846
    Alan Moore
    Dec 2, 2005
  5. GIMME
    Replies:
    3
    Views:
    11,952
    vforvikash
    Dec 29, 2008
Loading...

Share This Page