I'm working on learning how to use regular expressions, and have found a conversion that has me stuck.

Given the statements:

1. pi=3.14 and pie
2. pie and pi=3.14

How do I match pi and turn it in to 3.14 without also catching pie? This is user input, so I can't rely on position in the string.

My attempt was:
s/pi\W/3.14/g

That almost worked, but the \W ate the equals sign so I got:
3.143.14 and pie

Thanks in advance for any help. (This is not homework, but it is school related.)

Use this replace block: `s|((?<![\w\d])pi(?![\w\d]))|3.14|g` It has a negative lookbehind (?<![\w\d]) and lookahead (?![\w\d]) for characters preceeding and following the word pi. For more about lookahead/behinds:

Proofs:

``````my (\$in) = "8 * pie";
\$in =~ s/((?<![\w\d])pi(?![\w\d]))/3.14/g;
#result: \$in = 8 * pie
my (\$in) = "epi * 7";
\$in =~ s/((?<![\w\d])pi(?![\w\d]))/3.14/g;
#result: \$in = epi * 7
my (\$in) = "pi * 4";
\$in =~ s/((?<![\w\d])pi(?![\w\d]))/3.14/g;
#result: \$in = 3.14 * 4
my (\$in) = "pi * 4 * epi + pi / pie";
\$in =~ s/((?<![\w\d])pi(?![\w\d]))/3.14/g;
#result: \$in = 3.14 * 4 * epi + 3.14 / pie``````

PS: You may want to do another replace for multiplication shorthand: on paper 3PI * 4 is valid math markup; but if your passing this through an eval block; 3[pi replaced] isn't going to be the same. The block I've given you will NOT replace instances like this: 3PI. but it would replace the PI in instances like this: 3 PI (the space between 3 and PI is the key here). On that capitilized note, you may want to replace the "pi" in the block with (pi|PI|pI|Pi) a-la: `\$in =~ s/((?<![\w\d])(pi|PI|pI|Pi)(?![\w\d]))/3.14/g;` or do:

``````\$in = lc(\$in); #convert characters to lowercase
\$in =~ s/((?<![\w\d])pi(?![\w\d]))/3.14/g;``````

parsing user input for all possible syntax variations is an excersize in frustration as Matts code above shows. If you want to simply find "pi=3.14" a turn it into 3.14:

``s/pi=3\.14/3.14/g;``

or if 'pie=3.14' is a possibility too:

``s/pie?=3\.14/3.14/g;``

and last, if case sensitive matching is not wanted:

``s/pie?=3\.14/3.14/ig;``

Thanks for the help! I'll take apart the regexp and figure out what each part does. :-)

Implicit multiplication gets hard when you stop limiting variable names to one letter... but it's the better way to do it!