views:

42

answers:

2

Suppose I have a string like "abc | xyz" and I'd like to turn it into "xyz | abc" using only a regular expression substitution. (For this example there may be better ways, but this is a stand-in for something hairier.)

The following code doesn't do what I expect:

x = "abc | xyz"
x = x.gsub(/^([^\|\s]*)\s*\|\s*(\S*)/, "\2 | \1")
puts x

Is it obvious what I'm doing wrong? Thanks!

+4  A: 

You need to escape the backslashes in your replacement string. For example,

x = "abc | xyz"
x = x.gsub(/^([^\|\s]*)\s*\|\s*(\S*)/, "\\2 | \\1")
puts x

or just

x = "abc | xyz"
x = x.gsub(/^([^\|\s]*)\s*\|\s*(\S*)/, '\2 | \1')
puts x

and for bonus points, a simpler regex:

x = "abc | xyz"
x = x.gsub(/(.*) \| (.*)/, '\2 | \1')
puts x
Peter
Ha, makes perfect sense now. Thanks so much!
dreeves
+5  A: 

And there's always more than one way to do it..

 "abc | xyz".split(' | ').reverse.join(' | ')
DGM
Please don't say that - the Perl folks are going to sue for trademark infringement! :)
Andrew Grimm
Personally, I prefer seeing it done this way than with a regex.
Greg
granted, the original question indicated that the real need was far more complex... but this does illustrate how ruby can approach problems in different ways.
DGM
It's true that this was a toy example to illustrate my boneheaded regex bug, but that aside, I'm not sure this way is better than the regex way. Namely, I suspect this way isn't robust to varying amounts of whitespace surrounding the "|" character. True? Fixable? (Thanks again for the answers, btw!)
dreeves
yes, most of the time I think I would use gsub... the reverse split thing is just nice when you want it to be clear that you are reversing the order. However, split *can* take a regex as a param, so it can handle somewhat more complicated cases, but ultimately, the delimiter between data points must be able to be specified with one regex. In this case, if the white space was optional, you could: `"abc | xyz".split(/\s*\|\s*/).reverse.join(' | ')`
DGM
Doh, I was going to link to the docs too. http://ruby-doc.org/core/classes/String.html#M000803
DGM