Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Web CMS (TeamSite)
more regex
nipper
Trying to replace a string in a bunch of DCRs, with the exception of one part.
First thought:
$chamge_from="something";
$change_to="else";
$dont_change="something I want to preserve";
slurp DCR into $txt
How can I change $txt any instance of $change_from that is not in $dont_change ?
my current answer is
$txt =~ s/$dont_change/"ANDYSAYSSAVETHIS"/g;
$txt =~ s/$change_from/$change_to/g;
$txt =~ s/"ANDYSAYSSAVETHIS"/$dontchange/g;
Got to think there is a better way.
Andy
Find more posts tagged with
Comments
Adam Stoller
Actually, that's probably not a bad way to do it - simple and accurate - though you want to use the 's' modifier in addition to the 'g' modifier on the substitutions since you may have embedded newlines with $txt;
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
Migrateduser
The "right" way to do it would be with lookahead and lookbehind assertions (if my assumptions about what he means about the text he doesn't want to change being 'inside' something he does want to change are correct) - but, I like the approach he's using. It seems robust, and it would be easy for even a complete newcomer to understand what he's doing.
If you can give us a more accurate sample of the data, I might be able to tell you what the regex would look like with some assertions.
Migrateduser
That would certainly work but what about:
s/$change_from([^$dont_change])/$change_to/gs;
For your specific example, it would work but if there are variations of $dont_change, Perl may complain.
Dave
dave@simpleinternet.com
+USA (215) 962-5153
Migrateduser
s/$change_from(
[^$dont_change]
)/$change_to/gs;
This syntax doesn't work with strings, only sets of characters. This won't do what you want it to do.
Dave Smith
Sr. Software Engineer
Nike, Inc.
(503) 671-4238
DavidH.Smith@nike.com
BSS-2460_02.JPG
Migrateduser
That wouldn't work (again, assuming my assumptions about what his data is actually like are true).
in your example, whatever letters were in $dont_change would become a character class. Let's say $dont_change eq "cat".
Then what you have reads "match the contents of $change_from, followed by one character that is not a c, an a, or a t) and replace that with the string in $change_to.
Maybe you were going after something like:
s/$change_from(?!dont_change)/$change_to/gs;
but that's back to my idea of using the lookahead assertions. I think for his example though, since he says "in", that you also would need to do some look behind as well.
jbonifaci
Andy,
You can just count on the regex being greedy and do something like the code below. Being greedy, it will always match $doNotChange if it can, otherwise it will match $changeFrom. You then test to see if it matched just $changeFrom, and if it did, replace it, otherwise leave it alone.
use strict;
my $text = <<TEXT;
This is text, feel free to change it.
This is my text, leave it alone.
This is text, feel free to change it.
This is my text, leave it alone.
This is text, feel free to change it.
This is my text, leave it alone.
TEXT
my $changeFrom = "text";
my $changeTo = "your text";
my $doNotChange = "my text";
$text =~ s/($changeFrom|$doNotChange)/eval($1eq"$changeFrom")?$changeTo:$1/eg;
print $text;
Hope this helps,
~Jeff