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

Hello

I was tried to parse and order something like this

my $x = "<0>"; for (('<1>','<2>','<3>')) { $x =~ s/(<0>)/${1}${_}/; }

so i get this output:

<0> <3> <2> <1>

But i want to order from smaller to bigger

<0> <1> <2> <3>

how can i do to change it using regexp option, I was saw c modifier and \G, but i'm not sure how to use that

my $x = "<0>"; for (('<1>','<2>','<3>')) { if ($x =~ /<\d>/gc) { $x =~ s/(\G<\d>)/${1}${_}/g; } }

i was saw too pos function but it's a read only funcion or what's SCALAR mean in the documentation.

Thank a lot in advance

Nicolais

-----------------------------

Update: Basicaly i was tried to replace in the last match, how could i do that? using regexp only and of course it functions like pos, the best and good style way.

Replies are listed 'Best First'.
Re: How to start regexp from a X position
by ikegami (Patriarch) on Oct 07, 2008 at 11:35 UTC

    It's hard to tell what a good solution would be without knowing more about the real problem. I can think of two trivial solutions.

    • Use reverse to process the items in the opposite order.

      my $x = "<0>"; for (reverse '<1>', '<2>', '<3>') { $x =~ s/(<0>)/${1}${_}/; }
    • Just do one replace.

      my $x = "<0>"; $x =~ s/(<0>)/$1 . join('', '<1>', '<2>', '<3>')/e;

      Yes, many thank

      I wasn't clear about the question, basicaly i want replace in the last match, using only regexp and it's funcion like pos, in fact, i couldn't understand how pos function apart of course that retrieve the last position.

      Thank, ikegami

        basicaly i want replace in the last match

        Why? If you've just put it there, why would you like to proceed to replace it?

        using only regexp and it's funcion like pos

        Why? It's odd to tell someone how to solve a problem you can't solve.

Re: How to start regexp from a X position
by JavaFan (Canon) on Oct 07, 2008 at 12:09 UTC
    Here a way of doing it with pos:
    my $x = "<0>"; my $pos = 0; for (qw {<1> <2> <3>}) { pos($x) = $pos; $x =~ s/\G(<\d+>)/$1$_/; $pos += length $1; } say $x; __END__ <0><1><2><3>

      Thank!! great!!!, you open my mind, really i was knew that the solution is around that but i couldn't understand the documentation, perfect!!!!.

      One last question, how works the modifier c and \G in a regexp

      Could i do something like this:

      my $x = "<0>"; for (qw {<1> <2> <3>}) { if ($x =~ /<\d+>/gc) { $x =~ s/\G(<\d+>)/$1$_/; } } say $x;

      Really thank JavaFan

        I've no idea how to incorporate the /c modifier. It'll be pointless for two reasons. First, one sets pos() before matching, so who cares about the effect of /c. Second, /c would only kick in if you add a substring foo to $x, and the next time around, foo isn't there.

        Thank!! great!!!, you open my mind,

        You picked the worst of the presented solutions solely because it used pos as you initially believed it should. That's the very definition of a closed mind.

Re: How to start regexp from a X position
by JavaFan (Canon) on Oct 07, 2008 at 11:41 UTC
    pos is not a read-only function, you can actually assign to it. However, that won't help you much, as you're matching <0>, and that only occurs once in the string.

    As for you example, it can be written as:

    $x =~ /(<0>)/$1<1><2><3>/

      Thank for your reply

      Yes, i matching <0> in the first example, but i can change it to <\d>, could be it help me with pos?

      i'm not put the question cleary, i was tried to replace in the last match, how could i do that?

      Thank again

        You can get the last match by adding .* in front of the regex.

        If you use perl 5.10.0 or newer, you can make use of the \K ("keep") assertion:

        use 5.010; my $str = '<1> <2> <3>'; $str =~ s/.*\K<\d>/<4>/; say $str; __END__ <1> <2> <4>

        If you want to add test after the match, you can use s/.*<\d>\K/ <4>/ instead.

        for ('<1>', '<2>', '<3>') { $x =~ /^(.*<\d>)/$1$_/s; }
        is just a complicated way of doing
        $x =~ /^(.*<\d>)/$1<1><2><3>/s;