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

I need to do the following find and replace. i.e. need to fill in the 'refid' by matching the 'label' text. Unfortunately my script is producing unexpected outputs. pls review

Input:

<crossRef refid="">xx</crossRef> <crossRef refid="">yy</crossRef> <affiliation id="aff01"><label>xx</label> <affiliation id="aff02"><label>yy</label>
Output:
<crossRef refid="aff01">xx</crossRef> <crossRef refid="aff02">yy</crossRef> <affiliation id="aff01"><label>xx</label> <affiliation id="aff02"><label>yy</label>
my code:
if (/<affiliation id="(.+?)"><label>(.+?)<\/label>/) { $affid=$1; $afflbl=$2; s!<crossRef refid="(.*?)">$afflbl</crossRef>!<crossRef refid="$a +ffid">$afflbl</crossRef>!g; }
my code is not working properly. please suggest me the correct way of doing it.

Replies are listed 'Best First'.
Re: find and replace
by Zaxo (Archbishop) on Dec 21, 2007 at 07:55 UTC

    If you're reading that line by line, you can't easily back up to make the replacement.

    If you slurp the input, you need to save multiple matches for "affiliation" tags in a data structure and make another pass.

    If your input is valid XML, then one of the XML modules may be the best approach.

    After Compline,
    Zaxo

Re: find and replace
by vivid (Beadle) on Dec 21, 2007 at 09:36 UTC

    Try this

    my %aff; while($str=~/<affiliation id="([^"]*)"><label>(.+?)<\/label>/sgi){ $aff{$1}=$2; } for my $affid (sort keys %aff){ $str=~s#(<crossRef refid=")(">\Q$aff{$affid}\E</crossRef>)#$1$affid$2# +sgi; }

    Vivid