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

Dear Monks,

I want to sort the attribute values inside <tag refid="5,8,7,3,2,1"> and remove the commas.

i.e. input: <tag refid="5,8,7,3,2,1"> some other text
output: <tag refid="1 2 3 5 7 8"> some other text

test.txt:
<tag refid="5,8,7,3,2,1"> some other text

open(IN, "<test.txt") || die "\nCan't open test.txt \n"; $/=""; { local $/ = '<tag refid="'; print OUT scalar <IN>; for (<IN>) { s@(.*?)">@ my $var = $1; $var @e; print "$_\n" for sort { $a cmp $b } split /,/; } } close(IN); close(OUT);
but my present code is printing wrong with extra text.
1 some other text 2 3 5 7 8
Pls help me in correcting this.

Replies are listed 'Best First'.
Re: sorting difficulty
by moritz (Cardinal) on May 07, 2008 at 09:59 UTC
    use strict; use warnings; my $str = q{<tag refid="5,8,7,3,2,1">}; sub sort_and_reformat { my $s = shift; return join " ", sort split m/,/, $s; } $str =~ s/"([^"]*)"/'"' . sort_and_reformat($1) . '"'/eg; print $str, $/;

    The regex isn't very selective about what it considers an attribute, so you might want to tweak that.

    Update: You can use look-ahead and -behind to get rid of that ugly substitution body:

    $str =~ s/(?<=")([^"]*)(?=")/sort_and_reformat($1)/eg;

    If you want to be more specific about what to match, you can use something like this:

    $str =~ s/(?<=<tag refid=")([^"]*)(?=")/sort_and_reformat($1)/eg;
      hi, thanks for your reply. $str =~ s/(?<=<tag refid=")([^"]*)(?=")/sort_and_reformat($1)/eg; is not removing commas. also, 1 more doubt, some times i might need to sort alphabets too, e.g. <tag refid="c,b,a">
        is not removing commas.

        Did you even try it? It works for me. If it really doesn't work for you: What version of perl are you using, and what's the result on your perl?

        If you want to sort both numbers and letters correctly, you should use Sort::Naturally (and replace sort with nsort).

Re: sorting difficulty
by jwkrahn (Abbot) on May 07, 2008 at 10:14 UTC
    $ echo ' Dear Monks, I want to sort the attribute values inside <tag refid="5,8,7,3,2,1"> a +nd remove the commas. i.e. input: <tag refid="5,8,7,3,2,1"> some other text output: <tag refid="1 2 3 5 7 8"> some other text test.txt: <tag refid="5,8,7,3,2,1"> some other text ' | perl -e' $/ = ">"; while ( <> ) { s{(<tag refid=")([0-9,]+)(">)\z}{$1@{[ sort { $a <=> $b } $2 =~ /\ +d+/g ]}$3}; print; } ' Dear Monks, I want to sort the attribute values inside <tag refid="1 2 3 5 7 8"> a +nd remove the commas. i.e. input: <tag refid="1 2 3 5 7 8"> some other text output: <tag refid="1 2 3 5 7 8"> some other text test.txt: <tag refid="1 2 3 5 7 8"> some other text