Thursday, October 22, 2009

Recipe 1.4. Reversing a String by Words or Characters










Recipe 1.4. Reversing a String by Words or Characters







Problem


The letters (or words) of your string are in the wrong order.




Solution


To create a new string that contains a reversed version of your original string, use the reverse method. To reverse a string in place, use the reverse! method.



s = ".sdrawkcab si gnirts sihT"
s.reverse # => "This string is backwards."
s # => ".sdrawkcab si gnirts sihT"

s.
reverse! # => "This string is backwards."
s # => "This string is backwards."



To reverse the order of the words in a string, split the string into a list of whitespaceseparated words, then join the list back into a string.



s = "order. wrong the in are words These"
s.split(/(\s+)/).
reverse!.join('') # => "These words are in the wrong order."
s.split(/\b/).reverse!.join('') # => "These words are in the wrong. order"





Discussion


The
String#split
method takes a regular expression to use as a separator. Each time the separator matches part of the string, the portion of the string before the separator goes into a list. split then resumes scanning the rest of the string. The result is a list of strings found between instances of the separator. The regular expression /(\s+)/ matches one or more whitespace characters; this splits the string on word boundaries, which works for us because we want to reverse the order of the words.


The regular expression \b matches a word boundary. This is not the same as matching whitespace, because it also matches punctuation. Note the difference in punctuation between the two final examples in the Solution.


Because the regular expression /(\s+)/ includes a set of parentheses, the separator strings themselves are included in the returned list. Therefore, when we join the strings back together, we've preserved whitespace. This example shows the difference between including the parentheses and omitting them:



"Three little words".split(/\s+/) # => ["Three", "little", "words"]
"Three little words".split(/(\s+)/)
# => ["Three", " ", "little", " ", "words"]





See Also


  • Recipe 1.9, "Processing a String One Word at a Time," has some regular expressions for alternative definitions of "word"

  • Recipe 1.11, "Managing Whitespace"

  • Recipe 1.17, "Matching Strings with Regular Expressions"













No comments:

Post a Comment