rubyguides

String#match

String#match searches a string for a pattern and returns a MatchData object if found, or nil if not.

Signature

str.match(pattern, pos = 0)

Parameters:

  • pattern — a Regexp or String
  • pos — optional starting position (Integer)

Returns: MatchData, or nil if no match.

Basic Matching

Match a pattern and get back a MatchData object:

"hello".match(/o/)       # => #<MatchData "o">
"hello".match(/x/)       # => nil

The MatchData object contains the full match and any capture groups.

Using a String as the Pattern

You can pass a string — it gets converted to a Regexp:

"hello".match("o")       # => #<MatchData "o">
"hello".match("l")       # => #<MatchData "l">

Getting Match Details

The MatchData object gives you access to the match and its position:

m = "hello".match(/o/)
m[0]                      # => "o"      (the full match)
m.begin(0)                # => 4        (character position)

m = "hello".match(/(.)o/)
m[0]                      # => "lo"     (full match)
m[1]                      # => "l"      (first capture group)
m.begin(1)                # => 3

Capture Groups

Access numbered and named capture groups:

m = "john doe".match(/(?<first>\w+) (?<last>\w+)/)
m[0]                      # => "john doe"
m[1]                      # => "john"
m[2]                      # => "doe"
m[:first]                 # => "john"
m[:last]                  # => "doe"

If no match, match returns nil — calling m[1] on nil raises an error.

Pre-Match and Post-Match

Get the text before and after the match:

m = "hello".match(/l+/)
m.pre_match               # => "he"
m.post_match             # => "o"

Starting Position

The second argument lets you start searching from a given position:

"hello".match(/o/)        # => #<MatchData "o">
"hello".match(/o/, 0)     # => #<MatchData "o">
"hello".match(/o/, 5)     # => nil  (past the end)
"hello".match(/o/, 3)     # => #<MatchData "o">  (from char 3)

This is useful when you need to find matches after a certain point in the string.

Using a Block

When given a block, match returns the block’s return value:

"hello".match(/[aeiou]/) { |m| m[0].upcase }   # => "E"
"hello".match(/x/) { |m| m[0] }               # => nil

The block receives the MatchData object.

Match vs Other Methods

String#match is shorthand for calling Regexp#match on the string:

"hello".match(/o/)
# is equivalent to:
Regexp.new("o").match("hello")

Compare with String#=~ which returns the position (or nil):

"hello" =~ /o/        # => 4
"hello" =~ /x/        # => nil

And String#match? which returns true/false:

"hello".match?(/o/)   # => true
"hello".match?(/x/)   # => false

Practical Examples

Safely Accessing Capture Groups

Always check for nil before accessing groups:

def extract_year(text)
  m = text.match(/(\d{4})/)
  if m
    m[1]
  else
    nil
  end
end

extract_year("Version 2024")   # => "2024"
extract_year("No year")        # => nil

Multiple Patterns

Try multiple patterns in sequence:

def classify_input(input)
  case input
  when input.match?(/^\d+$/)
    "integer"
  when input.match?(/^\d+\.\d+$/)
    "float"
  when input.match?(/^[a-zA-Z]+$/)
    "word"
  else
    "unknown"
  end
end

classify_input("42")      # => "integer"
classify_input("3.14")   # => "float"
classify_input("hello")  # => "word"

See Also