Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

My foo apparently isn't strong with respect to regular expression modifiers. The following code is meant to simply replace one child node for another, but I'm seeing that both child nodes are being replaced given that the end tag occurs in multiple locations.
#!/usr/bin/perl my $xml = "<root>\n\t<element attribute='foo'>\n\t\t<!-- -->\n\t</elem +ent>\n\t<element attribute='bar'>\n\t\t<!-- -->\n\t</element>\n</root +>"; print "before:\n"; print $xml, $/; my $node = "\t<element attribute='new'>\n\t</element>\n"; print $node, $/; my $name='foo'; $xml =~ s!\t<element attribute='$name'>.*</element>\n!$node!se; print "after:\n"; print $xml, $/;
What modifier am I missing here? Thanks.

Replies are listed 'Best First'.
Re: limiting regular expression greediness?
by The Mad Hatter (Priest) on Mar 21, 2004 at 01:36 UTC
    Try changing the .* to .*?. You might also consider using some of the XML modules on CPAN instead of regexes.
Re: limiting regular expression greediness?
by pbeckingham (Parson) on Mar 21, 2004 at 01:38 UTC

    Try making that .* a non-greedy .*?.

Re: limiting regular expression greediness?
by Caron (Friar) on Mar 21, 2004 at 07:13 UTC

    Instead of a non-greedy qualifier, you can use a negative look-behind assertion to get your replacement right. (See perlre)

    $xml =~ s#\t<element attribute='$name'>(?:.(?<!</element>))*</element> +\n#$node#s;

    Side note: the /s modifier is not needed here.