Regex - disincluding strings in a match

S

Steve Chiang

Hello,

How would one disinclue a string in a match? For example, I want to match
the next animal that comes after "dog", but don't want to match "dog":

cat cow dog monkey zebra

.... so I would want to match only "monkey". However, the order of the items
in the list may change anytime:

zebra monkey dog cow cat

.... so I would want to match only "cow" in this case since it follows "dog"
directly. Further, I am limited in that I cannot use back-references for
this.

Thanks,
Steve
 
E

Eric Schwartz

Steve Chiang said:
How would one disinclue a string in a match? For example, I want to match
the next animal that comes after "dog", but don't want to match "dog":

cat cow dog monkey zebra

my $string = "cat cow dog monkey zebra";
my $animal = "dog";
my (undef, $match) = $string =~ /(\Q$animal\E) (?!\1)(\w+)/;
print "Match: [$match]\n";

Look up "negative lookahead" in perlre for more details.
... so I would want to match only "cow" in this case since it follows "dog"
directly. Further, I am limited in that I cannot use back-references for
this.

Why not? Perl supports backreferences. If you're trying to do this
in a non-Perl language that supports regexes, then you'd best ask
there; regexes very a LOT between languages, and the only way to know
for sure is to check the docs for whatever language you're using.

Anyway, I'm sure you can see how to avoid backreferences in that code;
I'll leave eliminating them as an exercise for the reader.

-=Eric
 
I

ioneabu

Eric said:
Steve Chiang said:
How would one disinclue a string in a match? For example, I want to match
the next animal that comes after "dog", but don't want to match "dog":

cat cow dog monkey zebra

my $string = "cat cow dog monkey zebra";
my $animal = "dog";
my (undef, $match) = $string =~ /(\Q$animal\E) (?!\1)(\w+)/;
print "Match: [$match]\n";

Why not simply:

#!/usr/bin/perl

use strict;
use warnings;

my $string = "cat cow dog monkey zebra";

$string =~ /dog\s*(\w+)/;

print $1;

I know I am not really matching "the word after dog" exactly, but the
outcome is the same I think.

wana
 
E

Eric Schwartz

^^^^^^^^^^^^^^^^^^^^^^^^^
Why not simply:

#!/usr/bin/perl

use strict;
use warnings;

my $string = "cat cow dog monkey zebra";

$string =~ /dog\s*(\w+)/;

That matches "dog dog";
print $1;

My solution was just a touch more flexible than required (i.e., I made
the animal to look for variable), but definitely won't match "dog
dog" (assuming $animal eq "dog").
I know I am not really matching "the word after dog" exactly, but the
outcome is the same I think.

Actually, that's exactly what you are matching. It's just not what
the OP asked for.

-=Eric
 
F

Fabian Pilkowski

* Steve Chiang said:
How would one disinclue a string in a match? For example, I want to match
the next animal that comes after "dog", but don't want to match "dog":

cat cow dog monkey zebra

... so I would want to match only "monkey".
Further, I am limited in that I cannot use back-references for
this.

You could use a technique called "zero-width positive look-behind" and
is described in `perldoc perlre`. Unless you have perl installed on your
system read this document at <http://perldoc.perl.org/perlre.html>.

my $string = "cat cow dog monkey zebra";
print $string =~ m/(?<=dog\s)\S*/g;
__END__
monkey

regards,
fabian
 
C

Christopher Nehren

Further, I am limited in that I cannot use back-references for this.

Then perhaps you should ask your teacher for help if you can't figure it
out on your own.

Best Regards,
Christopher Nehren
 
X

xhoster

Steve Chiang said:
Hello,

How would one disinclue a string in a match? For example, I want to
match the next animal that comes after "dog", but don't want to match
"dog":

You either match the string, or you do not match the string. You cannot
match part of a string. You can *capture* part of a string. Is that
what you meant to ask?
 
T

Tad McClellan

[snip Eric's code]
Why not simply:

#!/usr/bin/perl

use strict;
use warnings;

my $string = "cat cow dog monkey zebra";

$string =~ /dog\s*(\w+)/;

print $1;


You should never use the dollar-digit variables unless you
have first ensured that the match *succeeded*.

print $1 if $string =~ /dog\s*(\w+)/;

I know I am not really matching "the word after dog" exactly, but the
outcome is the same I think.


What does it match when you try it with

$string = "cat cow dogma monkey zebra";

??
 
E

Eric Amick

You could use a technique called "zero-width positive look-behind" and
is described in `perldoc perlre`. Unless you have perl installed on your
system read this document at <http://perldoc.perl.org/perlre.html>.

my $string = "cat cow dog monkey zebra";
print $string =~ m/(?<=dog\s)\S*/g;
__END__
monkey

Almost--that will match the second "dog" in "dog dog". What you need is

print $string =~ m/(?<=dog\s)(?!dog)\S+/g;
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top