in reply to Re: How do I reverse the order of the first and last word of a string?
in thread How do I reverse the order of the first and last word of a string?

ok so trying to accomplish this task differently and on my own I am stuck once again. here is what I have.. $_ = "this is my program to reverse"; s/(\w+) (\w+)/$2 $1/; print; obviously this only swaps the first two words. I cannot figure out how to swap the first and last word this way. Is it even possible? I literally spent most of the day working on a program and this is the only thing I am stuck on. Please help.
  • Comment on Re^2: How do I reverse the order of the first and last word of a string?

Replies are listed 'Best First'.
Re^3: How do I reverse the order of the first and last word of a string?
by BrowserUk (Patriarch) on Mar 11, 2007 at 02:53 UTC

      You may want to fix that to properly handle punctuation and capitalization:

      $_ = 'This is the word.'; $_ =~ s[(^\w+)(\s.*\s)(\w+)([[:punct:]]?)$][\u$3$2\l$1$4]; print

      --
      print "Just Another Perl Adept\n";

      $s = 'Two words'; $s =~ s[(^\S+)(\s.*\s)(\S+$)][$3$2$1]; print $s; #Two words

      Oops! ;-)

        The OP asked for help, not a perfect solution. S'always good to leave a little something for them to do themselves. It encourages people to try and understand the help provided, rather than just using it verbatim.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^3: How do I reverse the order of the first and last word of a string?
by bart (Canon) on Mar 11, 2007 at 13:12 UTC
    That's a respectable attempt you've made. Like you said, the problem is that you're only swapping the first and the second word. You should also try to match the stuff between two words, and suddenly it's not longer impossible to match the first and the last word.

    If you try

    s/(\w+)(.*)(\w+)/$3$2$1/
    you'll see that you'll have some trouble with greediness of the middle match: the "last word" will match too little: I expect it to match just the last letter.
    s/(\w+)(.*?)(\w+)/$3$2$1/
    is the other extreme, and you'll match too little.

    I can think of two solutions:

    1. Use the (latter) non-greedy match, but anchor that far side to the end of the string:
      s/(\w+)(.*?)(\w+)$/$3$2$1/
      or
      s/(\w+)(.*?)(\w+)(\W*)$/$3$2$1$4/
    2. Require there's a word boundary just in front of the last match, and match greedily.
      s/(\w+)(.*)\b(\w+)$/$3$2$1/
    All untested, but I have faith. :)