Regular Expressions

Splitting Rails DOM ids with RegEx Look Aheads

by Irish on October 15, 2010

In my Rails erb views I make good use of the dom_id view helper method. It basically introspects the object you pass to it and creates a unique id to use in your markup, based on the object type and database id. So for example if I had a Post with id 1, I could do:

    1 
    2 <li id="<%= dom_id(@post) %>">
    3 

And it would be rendered as

    1 
    2 <li id="post_1">
    3 

This is fine until you use dom_id on an object with a compound name like EmailNotification. Now dom_id will create a unique id like

email_notification_1

Which is still good until I’m doing some front-end testing and I’m parsing these dom ids to find their related db records. Now I need to split “email_notification_1″ in a way that easily separates the object class from the identifier. How would you do that?

Well, what we can do here is use an advanced Regular Expression feature called a negative look ahead. We want to say, “split the string on the last underscore”.

A negative look ahead uses the ?! syntax in parenthesis, everything that follows ?! in the parenthesis will be used in the negative look ahead matching. So in our case we want to say, there should be a underscore that can be followed by any character except another underscore. The pattern would like like this:

/_(?!.*_)/

We can confirm in irb

$ ree-1.8.7-head > x = "email_notification_1234"
=> "email_notification_1234"
ree-1.8.7-head > klass, id = x.split(/_(?!.*_)/)
=> ["email_notification", "1234"]

Likewise, If we wanted to split the dom_id on the first underscore we could just use a regular look ahead. It is similar but uses the ?= syntax.

$ ree-1.8.7-head > x.split(/_(?=.*_)/)
=> ["email", "notification_1234"]

{ 1 comment }

The Ruby %r{} expression

by Irish on August 12, 2010

Tonight I was reading over some Ruby code in a gem I’m currently using and came across this line:

    1 string = mode.to_s
    2 string.gsub!(%r{(^.)|(_.)}) { |m| m[m.length-1,1].upcase }
    3 

Two things struck me about that second line. For one I’ve never used gsub and passed it a block, thats cool. And two, what is %r{} ? I’ve never seen that before. It turns out that in Ruby, the /…/ or %r… literals, and using the Regexp.new constructor are all the same thing. All ways of created a regular expression. I still think I prefer the look of the simple slashes /…/ though.

{ 4 comments }