Regex question. Oh I so cannot do regular expression matching.

Discussion in 'Perl Misc' started by grocery_stocker, Apr 14, 2009.

  1. I can't seem to get perl to match both the words 'chad' AND 'party'
    in the string "chad ttyp0 party". Below is what I attempted.

    [cdalten@localhost oakland]$ more match.pl
    #!/usr/bin/perl
    use warnings;

    #$string = `w | grep cdalten | grep telnet`;

    $test = "chad ttyp0 party";

    if ("$test" =~/(\bchad\b)(\bparty\b)/) {
    print "true \n";
    }
    [cdalten@localhost oakland]$ ./match.pl
    [cdalten@localhost oakland]$

    What am I doing wrong>
     
    grocery_stocker, Apr 14, 2009
    #1
    1. Advertising

  2. grocery_stocker

    perl Newbie Guest

    On Apr 14, 9:08 pm, grocery_stocker <> wrote:
    > I can't seem to get perl to match both the words 'chad' AND  'party'
    > in the string "chad ttyp0 party". Below is what I attempted.
    >
    > [cdalten@localhost oakland]$ more match.pl
    > #!/usr/bin/perl
    > use warnings;
    >
    > #$string = `w | grep cdalten | grep telnet`;
    >
    > $test = "chad ttyp0 party";
    >
    > if ("$test" =~/(\bchad\b)(\bparty\b)/)  {
    >     print "true \n";}
    >
    > [cdalten@localhost oakland]$ ./match.pl
    > [cdalten@localhost oakland]$
    >
    > What am I doing wrong>


    Add OR condition in your code

    if ("$test" =~/(\bchad\b) || (\bparty\b)/)
     
    perl Newbie, Apr 14, 2009
    #2
    1. Advertising

  3. grocery_stocker

    perl Newbie Guest

    On Apr 14, 9:08 pm, grocery_stocker <> wrote:
    > I can't seem to get perl to match both the words 'chad' AND  'party'
    > in the string "chad ttyp0 party". Below is what I attempted.
    >
    > [cdalten@localhost oakland]$ more match.pl
    > #!/usr/bin/perl
    > use warnings;
    >
    > #$string = `w | grep cdalten | grep telnet`;
    >
    > $test = "chad ttyp0 party";
    >
    > if ("$test" =~/(\bchad\b)(\bparty\b)/)  {
    >     print "true \n";}
    >
    > [cdalten@localhost oakland]$ ./match.pl
    > [cdalten@localhost oakland]$
    >
    > What am I doing wrong>


    You can use OR , AND operator as per your requirement

    1. if ("$test" =~/(\bchad\b)/ || "$test" =~/(\bparty\b)/ ) {
    2. if ("$test" =~/(\bchad\b)/ && "$test" =~/(\bparty\b)/ ) {
     
    perl Newbie, Apr 14, 2009
    #3
  4. grocery_stocker <> wrote:
    > I can't seem to get perl to match both the words 'chad' AND 'party'
    > in the string "chad ttyp0 party". Below is what I attempted.
    >
    > [cdalten@localhost oakland]$ more match.pl
    > #!/usr/bin/perl
    > use warnings;
    >
    > #$string = `w | grep cdalten | grep telnet`;
    >
    > $test = "chad ttyp0 party";
    >
    > if ("$test" =~/(\bchad\b)(\bparty\b)/) {


    Why are you quoting $test?

    This will only work if there were a string with "chad" and "party" with
    nothing between them but a wordbreak. Such a string doesn't exist
    (because you'd need a character to create the wordbreak).

    So you probably want either...

    if ($test =~/(\bchad\b)/ and
    $test =~/(\bparty\b)/) {

    (But that won't preserve $1 properly if you want to capture both items)

    or

    if ($test =~ /(\bchad\b).*(\bparty\b)/) {

    because there are actually characters between them.

    --
    Darren
     
    Darren Dunham, Apr 14, 2009
    #4
  5. grocery_stocker

    Uri Guttman Guest

    >>>>> "pN" == perl Newbie <> writes:

    pN> On Apr 14, 9:08 pm, grocery_stocker <> wrote:
    >> I can't seem to get perl to match both the words 'chad' AND  'party'
    >> in the string "chad ttyp0 party". Below is what I attempted.
    >>
    >> [cdalten@localhost oakland]$ more match.pl
    >> #!/usr/bin/perl
    >> use warnings;
    >>
    >> #$string = `w | grep cdalten | grep telnet`;
    >>
    >> $test = "chad ttyp0 party";
    >>
    >> if ("$test" =~/(\bchad\b)(\bparty\b)/)  {


    perldoc -q var

    don't quote scalar vars

    >>     print "true \n";}
    >>
    >> [cdalten@localhost oakland]$ ./match.pl
    >> [cdalten@localhost oakland]$
    >>
    >> What am I doing wrong>


    pN> Add OR condition in your code

    pN> if ("$test" =~/(\bchad\b) || (\bparty\b)/)

    huh? have you tried that yourself? also the OP wanted both words to
    match and your attempt implies OR. besides there is no boolean logic
    INSIDE regexes.

    but i have several questions for the OP. why are you grabbing both words
    when you only print true if you found them? if that is all you want then
    an external boolean test with two separate regexes:

    if ( $test =~ /\bchad\b/ && $test =~ /\bparty\b/ ) {

    if you want that in one regex you need to account for text between the
    two words:

    if ( $test =~ /\bchad\b.*\bparty\b/ ) {

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 14, 2009
    #5
  6. grocery_stocker <> wrote:
    >I can't seem to get perl to match both the words 'chad' AND 'party'
    >in the string "chad ttyp0 party". Below is what I attempted.


    >$test = "chad ttyp0 party";
    >if ("$test" =~/(\bchad\b)(\bparty\b)/) {


    Why are you quoting $test? Please see 'perldoc -q quoting':
    What's wrong with always quoting "$vars"?

    Your RE is trying to match a word boundary, followed by 'chad', followed
    by a word boundary, immediately followed by a word boundary, then
    'party', then another word boundary.

    Obviously your test data contains other characters between the word
    boundarybehind 'chad' and the word boundaryin front of 'party',
    therefore it cannot match.

    Depending upon what you want to achive you can either split the RE into
    two
    if ($test =~/\bchad\b/ and $test =~/\bparty\b/)
    or insert some RE between those two word boundaries that will suck up
    the additional characters, e.g.
    if ($test =~/(\bchad\b).*(\bparty\b)/)

    jue
     
    Jürgen Exner, Apr 14, 2009
    #6
  7. On Apr 14, 9:27 am, Uri Guttman <> wrote:
    > >>>>> "pN" == perl Newbie <> writes:

    >
    > pN> On Apr 14, 9:08 pm, grocery_stocker <> wrote:
    > >> I can't seem to get perl to match both the words 'chad' AND 'party'
    > >> in the string "chad ttyp0 party". Below is what I attempted.
    > >>
    > >> [cdalten@localhost oakland]$ more match.pl
    > >> #!/usr/bin/perl
    > >> use warnings;
    > >>
    > >> #$string = `w | grep cdalten | grep telnet`;
    > >>
    > >> $test = "chad ttyp0 party";
    > >>
    > >> if ("$test" =~/(\bchad\b)(\bparty\b)/) {

    >
    > perldoc -q var
    >
    > don't quote scalar vars
    >
    > >> print "true \n";}
    > >>
    > >> [cdalten@localhost oakland]$ ./match.pl
    > >> [cdalten@localhost oakland]$
    > >>
    > >> What am I doing wrong>

    >
    > pN> Add OR condition in your code
    >
    > pN> if ("$test" =~/(\bchad\b) || (\bparty\b)/)
    >
    > huh? have you tried that yourself? also the OP wanted both words to
    > match and your attempt implies OR. besides there is no boolean logic
    > INSIDE regexes.
    >
    > but i have several questions for the OP. why are you grabbing both words
    > when you only print true if you found them? if that is all you want then
    > an external boolean test with two separate regexes:
    >
    > if ( $test =~ /\bchad\b/ && $test =~ /\bparty\b/ ) {
    >
    > if you want that in one regex you need to account for text between the
    > two words:
    >
    > if ( $test =~ /\bchad\b.*\bparty\b/ ) {
    >


    The question stems from a much larger side/site specific project that
    I'm working on. I just couldn't figure out how to search for multiple
    words in a single line. I figured it would have been just easier to
    post the part of the code that was giving me grief.
     
    grocery_stocker, Apr 14, 2009
    #7
  8. On Apr 14, 9:27 am, (Darren Dunham) wrote:
    > grocery_stocker <> wrote:
    > > I can't seem to get perl to match both the words 'chad' AND 'party'
    > > in the string "chad ttyp0 party". Below is what I attempted.

    >
    > > [cdalten@localhost oakland]$ more match.pl
    > > #!/usr/bin/perl
    > > use warnings;

    >
    > > #$string = `w | grep cdalten | grep telnet`;

    >
    > > $test = "chad ttyp0 party";

    >
    > > if ("$test" =~/(\bchad\b)(\bparty\b)/) {

    >
    > Why are you quoting $test?
    >


    Because in the full size script, $test is actually...

    $test = `w | grep cdalten | grep party`;

    > This will only work if there were a string with "chad" and "party" with
    > nothing between them but a wordbreak. Such a string doesn't exist
    > (because you'd need a character to create the wordbreak).
    >
    > So you probably want either...
    >
    > if ($test =~/(\bchad\b)/ and
    > $test =~/(\bparty\b)/) {
    >
    > (But that won't preserve $1 properly if you want to capture both items)
    >
    > or
    >
    > if ($test =~ /(\bchad\b).*(\bparty\b)/) {
    >
    > because there are actually characters between them.
    >
     
    grocery_stocker, Apr 14, 2009
    #8
  9. grocery_stocker

    Uri Guttman Guest

    >>>>> "gs" == grocery stocker <> writes:

    gs> On Apr 14, 9:27 am, (Darren Dunham) wrote:
    >>
    >> Why are you quoting $test?
    >>


    gs> Because in the full size script, $test is actually...

    gs> $test = `w | grep cdalten | grep party`;

    so?? perl isn't the shell so it doesn't need quoting around single
    scalars even if they have blanks in them.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 14, 2009
    #9
  10. On Apr 14, 9:47 am, Uri Guttman <> wrote:
    > >>>>> "gs" == grocery stocker <> writes:

    >
    > gs> On Apr 14, 9:27 am, (Darren Dunham) wrote:
    > >>
    > >> Why are you quoting $test?
    > >>

    >
    > gs> Because in the full size script, $test is actually...
    >
    > gs> $test = `w | grep cdalten | grep party`;
    >
    > so?? perl isn't the shell so it doesn't need quoting around single
    > scalars even if they have blanks in them.
    >


    Actually, the script borks when I try to use backticks.

    [cdalten@localhost oakland]$ more match.pl
    #!/usr/bin/perl
    use warnings;

    #$string = `w | grep cdalten | grep telnet`;

    $test = `w | grep cdalten | grep telnet`;

    print $test;

    if ($test =~/(\bchad\b)/ && $test =~/(\btelnet\b)/ ) {
    print "true \n";
    }
    [cdalten@localhost oakland]$ ./match.pl
    cdalten pts/7 :0.0 Mon12 14:55 0.62s 0.24s telnet
    [cdalten@localhost oakland]$

    Ides why?
     
    grocery_stocker, Apr 14, 2009
    #10
  11. grocery_stocker

    Uri Guttman Guest

    >>>>> "gs" == grocery stocker <> writes:

    gs> Actually, the script borks when I try to use backticks.

    gs> [cdalten@localhost oakland]$ more match.pl
    gs> #!/usr/bin/perl
    gs> use warnings;

    use strict too.

    gs> $test = `w | grep cdalten | grep telnet`;

    perl can do the grep for you and faster than forking two external greps.

    gs> print $test;

    gs> if ($test =~/(\bchad\b)/ && $test =~/(\btelnet\b)/ ) {
    gs> print "true \n";
    gs> }
    gs> [cdalten@localhost oakland]$ ./match.pl
    gs> cdalten pts/7 :0.0 Mon12 14:55 0.62s 0.24s telnet

    do you see the word 'chad' there? i don't. it helps if you search for
    things that are actually in the text.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 14, 2009
    #11
  12. grocery_stocker wrote:
    > On Apr 14, 9:47 am, Uri Guttman <> wrote:
    >>>>>>> "gs" == grocery stocker <> writes:

    >> gs> On Apr 14, 9:27 am, (Darren Dunham) wrote:
    >> >>
    >> >> Why are you quoting $test?
    >> >>

    >>
    >> gs> Because in the full size script, $test is actually...
    >>
    >> gs> $test = `w | grep cdalten | grep party`;
    >>
    >> so?? perl isn't the shell so it doesn't need quoting around single
    >> scalars even if they have blanks in them.
    >>

    >
    > Actually, the script borks when I try to use backticks.
    >
    > [cdalten@localhost oakland]$ more match.pl
    > #!/usr/bin/perl
    > use warnings;
    >
    > #$string = `w | grep cdalten | grep telnet`;
    >
    > $test = `w | grep cdalten | grep telnet`;
    >
    > print $test;
    >
    > if ($test =~/(\bchad\b)/ && $test =~/(\btelnet\b)/ ) {
    > print "true \n";
    > }
    > [cdalten@localhost oakland]$ ./match.pl
    > cdalten pts/7 :0.0 Mon12 14:55 0.62s 0.24s telnet
    > [cdalten@localhost oakland]$
    >
    > Ides why?


    Yes, the string 'chad' cannot be found in the string 'cdalten pts/7
    :0.0 Mon12 14:55 0.62s 0.24s telnet'.



    John
    --
    Those people who think they know everything are a great
    annoyance to those of us who do. -- Isaac Asimov
     
    John W. Krahn, Apr 14, 2009
    #12
  13. On Apr 14, 11:07 am, Uri Guttman <> wrote:
    > >>>>> "gs" == grocery stocker <> writes:

    >
    > gs> Actually, the script borks when I try to use backticks.
    >
    > gs> [cdalten@localhost oakland]$ more match.pl
    > gs> #!/usr/bin/perl
    > gs> use warnings;
    >
    > use strict too.
    >
    > gs> $test = `w | grep cdalten | grep telnet`;
    >
    > perl can do the grep for you and faster than forking two external greps.
    >


    Could I write it with one call to perl grep() or would I have use two
    calls to grep()?
     
    grocery_stocker, Apr 14, 2009
    #13
  14. grocery_stocker

    Uri Guttman Guest

    >>>>> "gs" == grocery stocker <> writes:

    gs> On Apr 14, 11:07 am, Uri Guttman <> wrote:
    >> >>>>> "gs" == grocery stocker <> writes:

    >>

    gs> Actually, the script borks when I try to use backticks.
    >>

    gs> [cdalten@localhost oakland]$ more match.pl
    gs> #!/usr/bin/perl
    gs> use warnings;
    >>
    >> use strict too.
    >>

    gs> $test = `w | grep cdalten | grep telnet`;
    >>
    >> perl can do the grep for you and faster than forking two external greps.
    >>


    gs> Could I write it with one call to perl grep() or would I have use two
    gs> calls to grep()?

    either way depending on the regex you use. it is the same problem you
    have been working on with your if statement.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 14, 2009
    #14
  15. On Apr 14, 11:37 am, grocery_stocker <> wrote:
    > On Apr 14, 11:07 am, Uri Guttman <> wrote:
    >
    > > >>>>> "gs" == grocery stocker <> writes:

    >
    > > gs> Actually, the script borks when I try to use backticks.

    >
    > > gs> [cdalten@localhost oakland]$ more match.pl
    > > gs> #!/usr/bin/perl
    > > gs> use warnings;

    >
    > > use strict too.

    >
    > > gs> $test = `w | grep cdalten | grep telnet`;

    >
    > > perl can do the grep for you and faster than forking two external greps.

    >
    > Could I write it with one call to perl grep() or would I have use two
    > calls to grep()?



    And here is what I get when I try to use one call to grep().

    [cdalten@localhost oakland]$ more match3.pl
    #!/usr/bin/perl
    use warnings;
    use strict;

    my @this = grep("cdalten" && "telnet", `w`);

    print @this, "\n";

    [cdalten@localhost oakland]$ ./match3.pl
    11:48:46 up 9 days, 4:51, 5 users, load average: 0.98, 0.74, 0.70
    USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
    cdalten pts/1 :0.0 05Apr09 9days 0.36s 0.36s bash
    cdalten pts/2 :0.0 05Apr09 8days 3.28s 2.92s python
    cdalten pts/3 :0.0 Mon18 10:04 0.93s 0.56s /usr/
    bin/perl /
    cdalten pts/5 :0.0 11:17 0.00s 0.77s 0.05s /usr/
    bin/perl .
    cdalten pts/7 :0.0 Mon12 15:11 0.63s 0.25s telnet

    [cdalten@localhost oakland]$
     
    grocery_stocker, Apr 14, 2009
    #15
  16. grocery_stocker

    Uri Guttman Guest

    >>>>> "gs" == grocery stocker <> writes:

    gs> my @this = grep("cdalten" && "telnet", `w`);

    what do you think that is doing? the first arg to grep is an
    expression. period. so what do you think this does:

    $x = "cdalten" && "telnet" ?

    do you see any regex code there?

    please learn some more basic perl. what you are trying to do is not
    difficult but you are guessing and thrashing and not programming. if you
    don't know how grep works, the run perldoc -f grep. it will show you
    that it takes an EXPR as its first argument, not a regex. now regexes
    are the most common first arg with grep but they must be explicitly
    coded.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 14, 2009
    #16
  17. On Apr 14, 12:00 pm, Uri Guttman <> wrote:
    > >>>>> "gs" == grocery stocker <> writes:

    >
    > gs> my @this = grep("cdalten" && "telnet", `w`);
    >
    > what do you think that is doing? the first arg to grep is an
    > expression. period. so what do you think this does:
    >
    > $x = "cdalten" && "telnet" ?
    >
    > do you see any regex code there?
    >
    > please learn some more basic perl. what you are trying to do is not
    > difficult but you are guessing and thrashing and not programming. if you
    > don't know how grep works, the run perldoc -f grep. it will show you
    > that it takes an EXPR as its first argument, not a regex. now regexes
    > are the most common first arg with grep but they must be explicitly
    > coded.
    >


    And I really don't quite get how something like

    @this = grep(/\bcdalten\b/ && /\btelnet\b/, `w`);

    is faster than something like

    $test = `w | grep cdalten | grep telnet`;

    I mean, either way, grep is going to have to be called twice.
     
    grocery_stocker, Apr 14, 2009
    #17
  18. grocery_stocker

    Uri Guttman Guest

    >>>>> "gs" == grocery stocker <> writes:


    gs> And I really don't quite get how something like

    gs> @this = grep(/\bcdalten\b/ && /\btelnet\b/, `w`);

    that is grep inside perl. a subroutine. and it is called only once.

    gs> is faster than something like

    gs> $test = `w | grep cdalten | grep telnet`;

    that is grep the unix utility program which requires forking a
    subprocess and you do it twice.

    gs> I mean, either way, grep is going to have to be called twice.

    nope. they are different greps and the perl one is called only one time.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 14, 2009
    #18
  19. grocery_stocker <> wrote:
    >Could I write it with one call to perl grep() or would I have use two
    >calls to grep()?


    The grep() function takes an expression as its first argument. That
    means, as long as you can express the condition as an expression, it can
    be arbitrarily complex. And your trivial condition can certainly be
    expressed in a very simple expression.

    jue
     
    Jürgen Exner, Apr 14, 2009
    #19
  20. grocery_stocker <> wrote:
    >> please learn some more basic perl. what you are trying to do is not
    >> difficult but you are guessing and thrashing and not programming.


    I would word that much stronger: please learn some basic programming!
    And while we are at it: PLEASE get a better name. I really don't want to
    address you as Grocery.

    >And I really don't quite get how something like
    >
    >@this = grep(/\bcdalten\b/ && /\btelnet\b/, `w`);
    >
    >is faster than something like
    >
    >$test = `w | grep cdalten | grep telnet`;
    >
    >I mean, either way, grep is going to have to be called twice.


    Are you aware about the differnce between a program and a function?

    Version 1 creates 1 new process and launches w in that process. Then it
    captures the output and returns it to the Perl program where grep() just
    loops once over the in-memory data.

    Version 2 creates 1 new process, starts a shell in that process (because
    there are shell meta-characters in the command), then forks of 2 or even
    3 more new processes (depending on the implementation), establishes
    pipes between those processes, launches w, grep, and grep in those
    processes, coordinates read and write between those processes, and
    finally returns the final result to the Perl program.

    Do you have any idea how expensive starting a new process is?

    jue
     
    Jürgen Exner, Apr 14, 2009
    #20
    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. VSK
    Replies:
    2
    Views:
    2,380
  2. =?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:
    881
    Alan Moore
    Dec 2, 2005
  3. Xah Lee
    Replies:
    1
    Views:
    971
    Ilias Lazaridis
    Sep 22, 2006
  4. Xah Lee
    Replies:
    8
    Views:
    482
    Ilias Lazaridis
    Sep 26, 2006
  5. Xah Lee
    Replies:
    2
    Views:
    238
    Xah Lee
    Sep 25, 2006
Loading...

Share This Page