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 Stringpos— 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
- /reference/string-methods/match-p/ — returns true or false
- /reference/string-methods/scan/ — find all matches
- /reference/string-methods/sub/ — replace first match