Solved

# Perl subsituion

Posted on 2012-09-04
293 Views
So i'm trying to get my head around the =~ s///;

in the following test
@ =a
0=o
1=i

``````my \$test = "M\@r10n";  ## this should by Marion
\$test =~ s/\@/a/g;
\$test =~ s/0/o/g; # ok so far
print  \$test  outputs  Mar1on
# now test if 1 as a letter before or after it
\$test =~ s/\w(1)|(1)\w/i/g; # not good
print  \$test  outputs  Maion
``````

why is this picking up r1 and not just the 1 as i thought (1) puts the 1 into \$1 and this is what is substituted?

Thanx
0
Question by:trevor1940

LVL 25

Accepted Solution

Correct the (1) picks up the 1 and puts it into \$1 .. which allow it to be used in the substitution ... but the entire match string gets substituted.  Think about this one ...
\$test =~ s/(\w)1/\$1i/g;
0

LVL 84

Assisted Solution

\$test =~ s/\w(1)|(1)\w/i/g; # not good
print  \$test  outputs  Maion
What did you want as output?

i thought (1) puts the 1 into \$1
That's correct, but then you do not do anything with \$1

Did you perhaps want
\$test =~ s/\w(?=1)|(?<=1)\w/i/g;
which produces
Mai1in
or
\$test =~ s/(?<=\w)1|1(?=\w)/i/g;
which produces
Marion
0

LVL 84

Assisted Solution

in the following test
@ =a
0=o
1=i
Or did you want
\$test = 'M@r10n';
\$test =~ tr/@01/aoi/;
print \$test;
0

LVL 1

Author Comment

ozo

\$test =~ s/(?<=\w)1|1(?=\w)/i/g; worked

but what is (?<=\w) doing?

dose \$test =~ tr/@01/aoi/;  have to be in that order
eg

@ 0 1 = a o i
will

0 1 @ still = a o i or will become 0 i a
(spaces just for clarity)

I get what you doing your putting (\w) into \$1

so how do you combine
\$test =~ s/(\w)1/\$1i/g;
\$test =~ s/1(\w)/i\$1/g;

into one line?
0

LVL 84

Assisted Solution

so how do you combine
\$test =~ s/(\w)1/\$1i/g;
\$test =~ s/1(\w)/i\$1/g;

into one line?

\$test =~ s/(\w)1|1(\w)/\$1i\$2/g;
#or
s/(\w)1/\$1i/g, s/1(\w)/i\$1/g for \$test;
0

LVL 84

Expert Comment

\$test =~ tr/@ 0 1/a o i/;
can be
\$test =~ tr/0 1 @/o i a/;  # (spaces need to be in the same place on both sides)
0

LVL 84

Assisted Solution

perl -MYAPE::Regex::Explain -e "print YAPE::Regex::Explain->new(qr/(?<=\w)1|1(?=\w)/i)->explain"
The regular expression:

(?i-msx:(?<=\w)1|1(?=\w))

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?i-msx:                 group, but do not capture (case-insensitive)
(with ^ and \$ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
(?<=                     look behind to see if there is:
----------------------------------------------------------------------
\w                       word characters (a-z, A-Z, 0-9, _)
----------------------------------------------------------------------
)                        end of look-behind
----------------------------------------------------------------------
1                        '1'
----------------------------------------------------------------------
|                        OR
----------------------------------------------------------------------
1                        '1'
----------------------------------------------------------------------
(?=                      look ahead to see if there is:
----------------------------------------------------------------------
\w                       word characters (a-z, A-Z, 0-9, _)
----------------------------------------------------------------------
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------
0

LVL 84

Expert Comment

\$test =~ s/(\w)1|1(\w)/\$1i\$2/g;
and
s/(\w)1/\$1i/g, s/1(\w)/i\$1/g for \$test;
will have different results in the case of
\$test='M@r1110n'
0

LVL 25

Expert Comment

>> so how do you combine
>>  \$test =~ s/(\w)1/\$1i/g;
>>  \$test =~ s/1(\w)/i\$1/g;
>>into one line?

I wouldn't ... I was highlighting how the (selection) and \$1 are used.  I would go with ozo's solution and use the modifier's to make the (select) non selective "s/(?<=\w)1|1(?=\w)/i/g;".
0

LVL 1

Author Closing Comment

Thanx
Hope sharing points OK
0

## Featured Post

Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This video discusses moving either the default database or any database to a new volume.