Logo lr 1c3bec71c7d53d0051ed754194e6408a12981dd23dde1cd852b3c8f718c40b5b

3 Things You Should Know About Ruby's gsub Method With Blocks

String#gsub is a very useful Ruby method

3 Things You Should Know About Ruby's gsub Method With Blocks

String#gsub is a very common method in ruby. For example, if you wanted to replace all of the 0's in a string with 1's, you can use the gsub method.

# String.gsub(pattern, replacement)
"0000".gsub("0","1")
=> "1111"

We can also use a block with gsub to do some interesting things.

Let's see this in action by formatting a phone number.

Example:

  • "+15555555555" should be "+1 (555) 555-5555"
  • "555-555-5555" should be "(555) 555-5555"
  • "555 555 5555" should be "(555) 555-5555"
  • "555 bad-format" should return itself "555 bad-format"

There are enough edge cases with phone numbers to make this an interesting problem to solve. Without using the gsub block, this process would result in a lot of if statements and additional complexity. We can use regex to find the pattern and do the formatting in the block statement of the gsub method.

def format_phone_number(phone_number)
  phone_number.gsub(/\+?(\d+)?.*(\d{3}).*(\d{3}).*(\d{4}).*/) do
    if $1
      '+' + $1 + ' (' + $2 + ') ' + $3 + '-' + $4
    else
      '(' + $2 + ') ' + $3 + '-' + $4 
    end
  end
end

The regex can be broken down like this:

  • +?(\d+)? will find the country code
  • (\d{3}) will find 3 digits
  • (\d{3}) will find the next 3 digits
  • (\d{4}) will find the next 4 digits
  • .* between the groups is used to handle any following spaces or special characters

1. If no match is found the original string will be returned

If a poorly formatted number is used like the string "hello world" instead of "555-555-5555", then the block will never get called. This is because no match was found. Therefore "hello world" will be returned.

2. The matching string is what is passed into the block (not each individual match)

You may expect the block to iterate over the collection of matches. However, this is not what happens. Instead the entire string is passed into the block.

3. You can access matched groups inside the block with the variables $1, $2, $3, etc.

The parenthesis in our regular expression represent groups. These groups can be accessed in the block with $1, $2, $3, $4 variables. Group $1 being the country code and so on. In the example, the conditional "if $1" checks to see if the country code was provided. The formatting will either return a number with the international country code or without one.

The code above covers an example using String#gsub and a block statement. There are still more things you can learn about String#gsub.