Wednesday, June 30, 2010

using regex groups for ruby's gsub

I won't spend long on this. If you've done your due diligence and carefully read up on the way regex matching works in ruby, you wouldn't be on this page. If you were like me and figured that you could probably just nail it the first time without looking anything up, you might have written something like this:

cleaned_string = "7.30 AM".gsub(/(\d)\.(\d)/,"#{$1}:#{$2}")


This is about as completely wrong as you can get while still looking somewhat right (as I found out today). You see, the global variables like "$n" do indeed store the matched groups from regex operations....AFTER they've executed. At the time when these parameters to the gsub method are evaluated, these variables are still nil. Thus the string you end up with is something like ":0 AM".

Correct syntax for including matched groups from regex expressions?

cleaned_string = "7.30 AM".gsub(/(\d)\.(\d)/,'\1:\2')


this way it's evaluated later, after the method has been called. Note the single tick marks, as doubles will cause the slash-number combinations to be interpreted.

1 comment:

Benjamin Oakes said...

That bit me pretty hard at one point too. As far as I know the \1, \2, etc. syntax is pretty consistent across regex engines (including vim), so it's definitely worth learning.

Ruby also lets you pass a block, which is really awesome. It opens up a lot of possibilities.