match three digit number using regular expression

Discussion in 'Perl' started by championsleeper, Apr 5, 2004.

  1. i am trying to write a script that will:
    - check an integer value to see if it has a particular pattern
    (regular expression match)
    - tell me what the particular pattern is.

    I am searching integer numbers for three digit patterns of the form
    111, 222, ..., 999, 000. If the number contains one or more of these
    then I want the script to say the pattern I wanty has been matched and
    which pattern it has found.

    e.g
    252352524577778787 -> yes! 777
    18357000232333 -> yes! 000

    I have written a ksh script to do this but want to write something in
    awk or perl that can do the same (better portability). I've been
    reading up on regular expressions but to no avail. Ideally I'd like to
    do the matching without recourse to a loop which is what I currently
    have.

    Any ideas?
     
    championsleeper, Apr 5, 2004
    #1
    1. Advertising

  2. championsleeper

    Ed Morton Guest

    championsleeper wrote:
    > i am trying to write a script that will:
    > - check an integer value to see if it has a particular pattern
    > (regular expression match)
    > - tell me what the particular pattern is.
    >
    > I am searching integer numbers for three digit patterns of the form
    > 111, 222, ..., 999, 000. If the number contains one or more of these
    > then I want the script to say the pattern I wanty has been matched and
    > which pattern it has found.
    >
    > e.g
    > 252352524577778787 -> yes! 777
    > 18357000232333 -> yes! 000
    >
    > I have written a ksh script to do this but want to write something in
    > awk or perl that can do the same (better portability). I've been
    > reading up on regular expressions but to no avail. Ideally I'd like to
    > do the matching without recourse to a loop which is what I currently
    > have.
    >
    > Any ideas?


    The trivial solution is:

    awk '/000/ { print "yes! 000"; next }
    /111/ { print "yes! 111"; next }
    ....
    /999/ { print "yes! 999"; next }'

    If your pattern contains both "111" and "333" and you want both
    reported, just remove the "; next" from each line.

    Ed.
     
    Ed Morton, Apr 5, 2004
    #2
    1. Advertising

  3. championsleeper

    Daboo Guest

    @comp=('111','222','333','444','555','666','777','888','999','000');

    $num=252352524577778787;
    #$num=18357000232333;

    foreach (@comp)
    {
    $numfind=$_;
    $foo = grep(!/$numfind/, $num);
    print "$numfind: $foo\n";
    }

    HTH,

    Daboo

    --
    Daboo
    http://www.dienhart.com

    "championsleeper" <> wrote in message
    news:...
    > i am trying to write a script that will:
    > - check an integer value to see if it has a particular pattern
    > (regular expression match)
    > - tell me what the particular pattern is.
    >
    > I am searching integer numbers for three digit patterns of the form
    > 111, 222, ..., 999, 000. If the number contains one or more of these
    > then I want the script to say the pattern I wanty has been matched and
    > which pattern it has found.
    >
    > e.g
    > 252352524577778787 -> yes! 777
    > 18357000232333 -> yes! 000
    >
    > I have written a ksh script to do this but want to write something in
    > awk or perl that can do the same (better portability). I've been
    > reading up on regular expressions but to no avail. Ideally I'd like to
    > do the matching without recourse to a loop which is what I currently
    > have.
    >
    > Any ideas?
     
    Daboo, Apr 6, 2004
    #3
  4. Daboo wrote:
    > @comp=('111','222','333','444','555','666','777','888','999','000');
    >
    > $num=252352524577778787;


    You'd better make it a string.

    $num = '252352524577778787';

    > #$num=18357000232333;
    >
    > foreach (@comp)
    > {
    > $numfind=$_;
    > $foo = grep(!/$numfind/, $num);


    Why are you using grep() to match one scalar? If you are trying to
    find the number of occurrences of $numfind in $num, that's not the way
    to do it. This is one way:

    $foo = () = $num =~ /$numfind/g;

    > print "$numfind: $foo\n";
    > }


    This is an alternative, shorter Perl solution:

    $_ = '252352524577778787';
    print 'yes! ', $1 x 3, "\n" while /(\d)\1\1/g;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Apr 6, 2004
    #4
  5. championsleeper

    Berk Birand Guest

    On Mon, 05 Apr 2004 16:21:51 -0500, Ed Morton wrote:
    > The trivial solution is:
    >
    > awk '/000/ { print "yes! 000"; next }
    > /111/ { print "yes! 111"; next }
    > ....
    > /999/ { print "yes! 999"; next }'
    >
    > If your pattern contains both "111" and "333" and you want both
    > reported, just remove the "; next" from each line.


    You really don't have to do that. In my opinion this is not even
    considered programming, since it basically lists all possible choices.

    Here's a simple script thing I wrote that does what you want.

    #!/usr/bin/perl

    print "Gimme a number";

    $input = <STDIN>;

    if ($input =~ /.*(\d)\1\1.*/ ) { #this is the line that does it all
    print "found line", $1*111;
    } else {
    print "found nothing";

    }

    Basically the "if" line does everything. \d stands for digit. Since I put
    it in the brackets, I can refer to the number found later with \1.
    Translated to english, that would be:

    "Find a string starting with something, which includes a digit, followed
    by two instances of the same digit and finished by something else."

    We can then read the single digit value in perl using the special variable
    $1, which contains the result of the first parenthesis of the RegExp.
    Multiplying by 111 is simply a little math trick that will output the same
    digit thrice ( I couldn't find an operator that repeats a string ).

    Also, if you have multiple three consecutive digits, this will only math
    the *last* one. 8791118797666778 will return 666 only, and will discard
    the 111. Some more modifications are needed, and I am too lazy to do them
    now. If that is what you need, let me know.

    Cheers,
    BB
     
    Berk Birand, Apr 6, 2004
    #5
  6. championsleeper

    Ed Morton Guest

    Berk Birand wrote:
    > On Mon, 05 Apr 2004 16:21:51 -0500, Ed Morton wrote:
    >
    >>The trivial solution is:
    >>
    >>awk '/000/ { print "yes! 000"; next }
    >> /111/ { print "yes! 111"; next }
    >> ....
    >> /999/ { print "yes! 999"; next }'
    >>
    >>If your pattern contains both "111" and "333" and you want both
    >>reported, just remove the "; next" from each line.

    >
    >
    > You really don't have to do that. In my opinion this is not even
    > considered programming, since it basically lists all possible choices.


    It's arguably the best form of programming when providing code for
    beginners who haven't precisely specified their requirements and
    therefore may need to modify it themselves - KISS.

    > Here's a simple script thing I wrote that does what you want.


    Maybe.

    <snip>
    > Also, if you have multiple three consecutive digits, this will only math
    > the *last* one. 8791118797666778 will return 666 only, and will discard
    > the 111. Some more modifications are needed, and I am too lazy to do them
    > now. If that is what you need, let me know.


    Precisely. What I provided was something obvious that the OP could
    easily tweak based on their detailed requirements or enhance in future,
    plus the instructions on how to modify it. What you provided was
    something that, while it would concisely satisfy one interpretation of
    the requirements, would need non-trivial rework (I'm assuming that's the
    case or you'd have done it) to satisfy a different interpretation. Both
    solutions have some merit based on what the OP wants to get out of this
    exercise.

    Ed.
     
    Ed Morton, Apr 6, 2004
    #6
  7. Thanks to all for the help offered. Very much appreciated!
     
    championsleeper, Apr 6, 2004
    #7
    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. Fangs
    Replies:
    3
    Views:
    9,947
    darshana
    Oct 26, 2008
  2. VSK
    Replies:
    2
    Views:
    2,397
  3. Rune Strand
    Replies:
    9
    Views:
    401
    Bengt Richter
    Sep 6, 2004
  4. Steven
    Replies:
    8
    Views:
    503
    Arndt Jonasson
    Feb 3, 2006
  5. Thomas Andersson
    Replies:
    2
    Views:
    125
    Dr.Ruud
    Aug 14, 2010
Loading...

Share This Page