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:
regex question

 



yanivr78
Novice

Apr 2, 2013, 1:18 AM

Post #1 of 6 (529 views)
regex question Can't Post

Hi all,

I am trying to understand something regarding substitute in this code :


Code
$_ = "huge dinosaur"; 
s/\w+$/($`!)$&/; # Now it's "huge (huge !)dinosaur"
print "$_\n";



this is what I understand :
s/\w+$/
1) /w = search for a word
2) + = match at least 1 time.
3) $ = at the end of the line.

now comes the substitute part and in here I have my questions :
this is the change : ($`!)$&

1) what is $` ?
2) after $` place an exclamation mark.
3) what is $& ?

Many thanks for any answer !


Rahul6990
Novice

Apr 2, 2013, 2:10 AM

Post #2 of 6 (527 views)
Re: [yanivr78] regex question [In reply to] Can't Post

Hi yanivr78,

the s///; have two parts first is matching second is replacement.

In the first part we have:

\w+: will match more than one occurrence of single character.
$: will match the end of line, so
\w+$:will match a single word that comes at the end of sting which happens to be 'dinosaur'
now comes the second part ie replacement we have:

$`:The string preceding whatever was matched by the last pattern match(\w+$ has matched 'dinosaur' so its preceding was 'huge ')
($`!): will become (huge !)
$&:Contains the string matched by the last pattern match which is 'dinosaur'. so in the above regex we have replaced
'dinosaur' with '(huge !)dinosaur' rest of the string part is as it is so after the s/// operation you initial string is converted to 'huge (huge !)dinosaur'.

in the above example if you change

Code
$_ = "Hello Good Morning";

part the output will be

Code
Hello Good (Hello Good !)Morning



yanivr78
Novice

Apr 2, 2013, 2:53 AM

Post #3 of 6 (525 views)
Re: [Rahul6990] regex question [In reply to] Can't Post

Thanks for that,

Last 2 questions,
1) Does anybody know why there's a space in here : ($`!)
it shows as :
(huge !) ---> In here...Can I remove the space ?

2) in the source I use : \w+, I think that the + is useless right ?
can I use just \w ? if yes - well I tried...and it didnt work, this is the output :
huge dinosau(huge dinosau!)r


Thanks for any answer ! :)


(This post was edited by yanivr78 on Apr 2, 2013, 3:31 AM)


Rahul6990
Novice

Apr 2, 2013, 3:51 AM

Post #4 of 6 (518 views)
Re: [yanivr78] regex question [In reply to] Can't Post

Answers:

1. yes you can remove the space.

2. \w will try to match single character not a single word so in that case your single character at the line end (\w$) will be 'r' as a result of will $` is having 'huge dinosau'.

Wink


(This post was edited by Rahul6990 on Apr 2, 2013, 3:51 AM)


yanivr78
Novice

Apr 2, 2013, 4:05 AM

Post #5 of 6 (514 views)
Re: [Rahul6990] regex question [In reply to] Can't Post

I also now understand why there's a space...
the space is part of the preceding word !

Many thanks man ! :) that helps alot !


(This post was edited by yanivr78 on Apr 2, 2013, 4:07 AM)


Kenosis
User

Apr 2, 2013, 8:10 AM

Post #6 of 6 (503 views)
Re: [yanivr78] regex question [In reply to] Can't Post

The following variables are initialized by a successful regex:


Code
$`    Everything prior to matched string 
$& Entire matched string
$' Everything after to matched string


Source: perlreref

However, the above source says the following about their use:


Quote
The use of $` , $& or $' will slow down all regex use within your program.


Instead, we're encouraged to use the following:


Code
${^PREMATCH}  Everything prior to matched string 
${^MATCH} Entire matched string
${^POSTMATCH} Everything after to matched string


However, these will not work in the substitution. Instead, the better way to achieve the output you've shown is by using captures:


Code
use strict; 
use warnings;

$_ = "huge dinosaur";
s/(.+?)\K(\w+)$/($1!)$2/; # Now it's "huge (huge !)dinosaur"
print "$_\n";


At first glance, the above appears to add an unnecessary layer of complexity, as it's certainly not as easily read as the original regex. However, this will not incur the performance penalty that the original script costs.

Here's the regex explained:


Code
s/(.+?)\K(\w+)$/($1!)$2/ 
^ ^ ^ ^ ^ ^ ^
| | | | | | |
| | | | | | + - Use what was captured in the second group "(\w+)"
| | | | | + - Use what was captured in the first group "(.+?)"
| | | | + - The end of the line
| | | + - Match and capture one or more 'word' characters
| | + - Keep everything before the 'word' characters
| + - Match and capture one or more of any character (almost), but don't be 'greedy' (the effect of the "?")
+ - Begin substitution


Hope this helps!

 
 


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

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