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

G

grocery_stocker

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>
 
P

perl Newbie

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)/)
 
P

perl Newbie

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)/ ) {
 
D

Darren Dunham

grocery_stocker said:
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.
 
U

Uri Guttman

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
 
J

Jürgen Exner

grocery_stocker said:
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
 
G

grocery_stocker

"pN" == perl Newbie <[email protected]> writes:
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.
 
G

grocery_stocker

grocery_stocker said:
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`;
 
U

Uri Guttman

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
 
G

grocery_stocker

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?
 
U

Uri Guttman

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
 
J

John W. Krahn

grocery_stocker said:
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
 
G

grocery_stocker

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()?
 
U

Uri Guttman

gs> [cdalten@localhost oakland]$ more match.pl
gs> #!/usr/bin/perl
gs> use warnings;
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
 
G

grocery_stocker

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]$
 
U

Uri Guttman

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
 
G

grocery_stocker

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.
 
U

Uri Guttman

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
 
J

Jürgen Exner

grocery_stocker said:
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

Jürgen Exner

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top