p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   Perl (http://p2p.wrox.com/forumdisplay.php?f=196)
-   -   Regular Expression in Perl (http://p2p.wrox.com/showthread.php?t=54941)

CaNNaC March 5th, 2007 06:17 PM

Regular Expression in Perl
 
Hi everyone,
I am a new perl programmer and I have a problem with regular expressions in perl.
I wrote a regular expression in order to match a certain part of a string and then I wanted to be able get and change that part of the string (that is, matched substring), but I don't know how to get the matched substring and change it in perl. (I wrote the regular expression and it is working correctly and doing its job well)
For exampple;
Let's assume our string is, $str = "The men in the room looked at the Men in the street.", and I wrote a reg. expr. that matches /Men/, and I want to substitute -en-(in Men) to -an-. So, if I write the following code;
<code> if($str =~ m/Men/) {
          $str = s/en/an; } </code>
this code will change the -en- that is the first one (in men) in the string which is I don't want.

As a result, my problem is the same, I wrote a reg. expr., it matches a substr. but I am not able to change the content of that substr.

Please help, I know there is a way to make this in perl but I couldn't find it.

Thanks.





ciderpunx March 6th, 2007 08:35 AM

Hey CaNNaC,

You're nearly there. This will do it:

Code:

if ($str=~m/Men/) {
  $str =~ s/en/an/;
}

Cheers

--
Charlie Harvey's website - linux, perl, java, anarchism and punk rock: http://charlieharvey.org.uk

CaNNaC March 6th, 2007 10:03 AM

Quote:

quote:Originally posted by ciderpunx
You're nearly there. This will do it:
Code:

if ($str=~m/Men/) {
  $str =~ s/en/an/;
}


Thanks, I know that this will substitute -en- to -an-. This will just change the first -en- in the string to -an-, but I want to change the -en- in the matched reg. expr. In my example (The men in the room looked at the Men in the street), it will change -en- in men to -an-, but as you noticed I matched Men and I didn't change it. So, problem is how to get the content of matched string and change it without changing any other unmatched substring.

Thanks.


ciderpunx March 7th, 2007 07:32 AM

Ah ok

Code:

$str =~ s/(M)en/$1an/;
Or, more simply:

Code:

$str =~ s/Men/Man/;
If you want to change every instance then you can do

Code:

$str =~s/(M)en/$1an/g;
If you only want to change the word Men, and not Mendicant, for example, or HeMen then ad \b (word boundaries). i.e.

Code:

$str=~s/(\b)(M)en(\b)/$1$2an$3/;
This last example gives me

Code:

$ echo The men in the room looked at the Men in the street |  perl -pe 's/(\b)(M)en(\b)/$1$2an$3/g'
The men in the room looked at the Man in the street
$

You may want to downcase the M from Men, so you could do:

Code:

$ echo The men in the room looked at the Men in the street |  perl -pe 's/(\b)(M)en(\b)/$1\l$2an$3/g'
The men in the room looked at the man in the street
$

HTH
Charlie

--
Charlie Harvey's website - linux, perl, java, anarchism and punk rock: http://charlieharvey.org.uk

CaNNaC March 7th, 2007 05:33 PM

Hi Charlie,

Thanks for your help really. I thought the example I gave will solve my problem, but it didn't :(
In the example I just matched a string that I already know -that is Men-, but here is the problem if I write a reg. expr. instead of Men(again it may match Men but we don't know it), then it will match a string that we cannot predict exactly which word it will be.

For example:
Code:

my $word = "([a-z]|[A-Z])";
my $str = "I hope we-will-find (a-Solution)";

if($str =~ m/(\()($word+(\-$word+){1,}$word+)/(\))) {
   #here as it is seen from the reg. expr. I will match (a-Solution)
   #and I want to delete - in this matched substring without deleting the others
   #It should be (aSolution) after deletion. But we cannot know the substring that will match before it matches
   #as it is in previous example.
   $str =~ s/\-//;
   #if i write this, this will delete the first -, but not in the (a-solution.)
   #So, how can we tell it should delete the one that it matched in reg. expr.
}

Thanks for your help.



ciderpunx March 8th, 2007 09:12 AM

So are you after something that looks for anything in the string that is in brackets and then removes the '-' from it? You really don't need to match and then run the substitution. What you're doing at the moment is saying:

- Take a string
- See if it matches a pattern
- If it does match the pattern, match the whole string for a different pattern and substitute (in this case delete) it.

So for the string "I hope we-will-find (a-Solution)"

This
Code:

if($str =~ m/(\()($word+(\-$word+){1,}$word+)/(\))) {
   $str =~ s/\-//;
}

Will do exactly the same as this:
Code:

$str =~ s/\-//;
Because $str is always $str until you assign something else to it, or try and change it.

You could rewrite your example as:

Code:

$str="I hope we-will-find (a-Solution)"; # $str=="I hope we-will-find (a-Solution)"
$str=~s/(\(\w+)\-(\w+\))/$1 $2/;        # $str=="I hope we-will-find (a Solution)"
                                         # nb \w is a shortcut for [a-zA-Z_]
print "Got: '$str'";

--
Charlie Harvey's website - linux, perl, java, anarchism and punk rock: http://charlieharvey.org.uk

CaNNaC March 8th, 2007 03:01 PM

Hi Charlie,

Finally I solved the problem, and everything is really fine and I am comfortable with reg. expressions now.

Thanks.


crmpicco March 9th, 2007 06:47 AM

s/foo/bar/;
replaces the first occurrence of the exact character sequence foo in the "current string" (in special variable $_) by the character sequence bar; for example, foolish bigfoot would become barlish bigfoot

www.crmpicco.co.uk
www.ie7.com


All times are GMT -4. The time now is 11:23 AM.

Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.