CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
A simple regex question

 



lovinPerl
New User

Jan 18, 2013, 6:02 PM

Post #1 of 5 (1160 views)
A simple regex question Can't Post

This question is going to seem super basic (because it is)

pretty much, I have these codes, and they can be of the following two forms, (where a represents any letter):

aa* or a*a

So now, I know how to do pattern matching and I could do something like (/\w{2}\*/) - this would match the first type. However, I'm confused how to get the second type. I can't do (/\w\*\w/) because this would match a*b, or b*c, or g*l, or anything like that. The issue is the first and second letter must be the same. So, b*b is all right, z*z is all right, etc.


Edit: Think I figured it out! There is something in perl called pattern memory. I have done this:

if(m/(\w)\1\*/){
print "matched case one with $1";
}
if(m/(\w)\*\1/){
print "matched case two with $1";
}

this works! Apparently putting something in parens stores it as a variable, first $1, then $2, etc.

for some reason when I try to combine the two if statements by using brackets to give the OR condition,

if(m/[(\w)\1*/|(\w)\*\1]/){
print "print $1";
}

this doesn't seem to work


(This post was edited by lovinPerl on Jan 18, 2013, 7:14 PM)


BillKSmith
Veteran

Jan 18, 2013, 8:22 PM

Post #2 of 5 (1152 views)
Re: [lovinPerl] A simple regex question [In reply to] Can't Post

Yes, you did get it right. Note: You can combine the two forms using "non-capturing" parens.

Code
use strict; 
use warnings;
my $string = 'xx*';
if ( $string =~ m/(\w)(?:\*\1|\1\*)/ ) {
print $1, "\n";
}

Good Luck,
Bill


Laurent_R
Veteran / Moderator

Jan 19, 2013, 1:08 AM

Post #3 of 5 (1139 views)
Re: [lovinPerl] A simple regex question [In reply to] Can't Post

Bill gave you a solution, but just to point to your problem:


In Reply To

for some reason when I try to combine the two if statements by using brackets to give the OR condition,

if(m/[(\w)\1*/|(\w)\*\1]/){
print "print $1";
}

this doesn't seem to work


- The * marked in red above needs to be escaped
- the / marked in red above closes the pattern of your regex, so that the rest of your regex does not make sense.

You could have two regexes with a "or":


Code
if (/(\w)\1\*/  or  /(\w)\*\1/){


or, if you want to use an alternation, factoring the \w:


Code
if (m/(\w)((\1\*)|(\*\1))/) {


(You could modify the latest code above and add non capturing parens, but I pprefered not to do it here because it is not necessary and it would reduce overall legibility.)


lovinPerl
New User

Jan 19, 2013, 6:50 AM

Post #4 of 5 (1130 views)
Re: [lovinPerl] A simple regex question [In reply to] Can't Post

Thank you guys for the help. :D I'm having lots of fun with regex in perl now


7stud
Enthusiast

Jan 20, 2013, 12:38 PM

Post #5 of 5 (1114 views)
Re: [lovinPerl] A simple regex question [In reply to] Can't Post

One other thing...escaping things in regexes makes them very hard to read. One trick is to put the character inside a character class. Inside a character class, the special regex characters lose their special meaning. Also, using some whitespace to separate the parts of your regex (coupled with the x modifier) will make your regexes easier to read:


Code
if ( /(\w) \1 [*] | (\w) [*] \1/x )



(This post was edited by 7stud on Jan 20, 2013, 12:39 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives