Bird
Raised Fist0
Rubyprogramming~10 mins

Capture groups in Ruby - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Capture groups
Start with regex pattern
↓
Match string against pattern
↓
Find capture groups in parentheses
↓
Extract matched parts for each group
↓
Use captured groups for output or processing
↓
End
The regex engine matches the string, finds parts in parentheses as capture groups, and extracts them for use.
Execution Sample
Ruby
text = "Name: John, Age: 30"
pattern = /(Name: (\w+)), Age: (\d+)/
matches = text.match(pattern)
puts matches[1]
puts matches[2]
puts matches[3]
This code matches a string with a pattern having capture groups and prints each captured part.
Execution Table
StepActionEvaluationResult
1Define text stringtext = "Name: John, Age: 30"text holds the full string
2Define regex patternpattern = /(Name: (\w+)), Age: (\d+)/pattern has 3 capture groups
3Match text with patternmatches = text.match(pattern)matches is a MatchData object
4Access matches[1]matches[1]"Name: John" (whole first group)
5Access matches[2]matches[2]"John" (second group)
6Access matches[3]matches[3]"30" (third group)
7EndNo more stepsExecution complete
💡 All capture groups extracted and printed, match successful
Variable Tracker
VariableStartAfter Step 3After Step 4After Step 5After Step 6Final
text"Name: John, Age: 30""Name: John, Age: 30""Name: John, Age: 30""Name: John, Age: 30""Name: John, Age: 30""Name: John, Age: 30"
pattern/(Name: (\w+)), Age: (\d+)//(Name: (\w+)), Age: (\d+)//(Name: (\w+)), Age: (\d+)//(Name: (\w+)), Age: (\d+)//(Name: (\w+)), Age: (\d+)//(Name: (\w+)), Age: (\d+)/
matchesnilMatchData object with groups: ["Name: John", "John", "30"]SameSameSameSame
Key Moments - 3 Insights
Why does matches[1] return "Name: John" and not just "John"?
matches[1] returns the first capture group which is (Name: (\w+)), including "Name: John". The inner group (\w+) is matches[2], which returns just "John". See execution_table rows 4 and 5.
What happens if the pattern does not match the text?
If no match occurs, matches will be nil, so trying to access matches[1] would cause an error. The code assumes a successful match as shown in execution_table row 3.
Why do we use parentheses in the regex pattern?
Parentheses define capture groups that extract parts of the matched string separately. Without them, you get only the full match, not parts. This is shown in the pattern definition and extraction steps.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of matches[2] at step 5?
A"John"
B"Name: John"
C"30"
Dnil
💡 Hint
Check execution_table row 5 under Result column for matches[2]
At which step does the variable 'matches' become a MatchData object?
AStep 2
BStep 3
CStep 4
DStep 1
💡 Hint
Look at execution_table row 3 Action and Result columns
If the text was "Name: Alice, Age: 25", what would matches[3] be?
A"John"
B"Alice"
C"25"
D"Name: Alice"
💡 Hint
matches[3] captures the age number as shown in execution_table row 6
Concept Snapshot
Capture groups in Ruby regex are parts of the pattern inside parentheses.
They extract specific parts of a matched string.
Use match method to get a MatchData object.
Access groups with matches[1], matches[2], etc.
matches[0] is the full match.
Groups are numbered by their opening parenthesis order.
Full Transcript
This example shows how Ruby uses capture groups in regular expressions. We start with a text string and a regex pattern with parentheses marking capture groups. When we match the pattern against the text, Ruby returns a MatchData object. This object holds the full match and each captured group separately. We access these groups by index: matches[1] for the first group, matches[2] for the second, and so on. The example extracts the name and age from the string and prints them. Key points include understanding that parentheses define groups, groups are numbered by their order, and the match must succeed to access groups safely.

Practice

(1/5)
1. What does a capture group do in a Ruby regular expression like /(\d{3})-(\d{2})/?
easy
A. It repeats the pattern multiple times.
B. It saves parts of the matched text for later use.
C. It matches only digits without saving.
D. It ignores the matched text.

Solution

  1. Step 1: Understand capture groups in regex

    Capture groups are parts of a pattern enclosed in parentheses that save matched text.
  2. Step 2: Analyze the example pattern

    The pattern /(\d{3})-(\d{2})/ has two capture groups for three digits and two digits separated by a dash.
  3. Final Answer:

    It saves parts of the matched text for later use. -> Option B
  4. Quick Check:

    Capture groups = save matched parts [OK]
Hint: Parentheses in regex save matched text as groups [OK]
Common Mistakes:
  • Thinking capture groups repeat patterns
  • Confusing capture groups with non-capturing groups
  • Believing capture groups ignore matched text
2. Which of the following is the correct syntax to create a capture group in a Ruby regex?
easy
A. /(abc)/
B. /[abc]/
C. /{abc}/
D. /abc/

Solution

  1. Step 1: Identify capture group syntax

    Capture groups in Ruby regex are created by enclosing the pattern in parentheses ().
  2. Step 2: Compare options

    /(abc)/ uses parentheses correctly. /[abc]/ uses square brackets which match any one character. /{abc}/ uses curly braces which are quantifiers. /abc/ has no capture group.
  3. Final Answer:

    /(abc)/ -> Option A
  4. Quick Check:

    Parentheses = capture group [OK]
Hint: Use parentheses () for capture groups in regex [OK]
Common Mistakes:
  • Using square brackets [] instead of parentheses
  • Using curly braces {} incorrectly
  • Forgetting parentheses for capture groups
3. What will be the output of this Ruby code?
text = "Order 123-45"
match = text.match(/(\d{3})-(\d{2})/)
[match[0], match[1], match[2]]
medium
A. ["123-45", "45", "123"]
B. ["12345", "123", "45"]
C. ["Order 123-45", "123", "45"]
D. ["123-45", "123", "45"]

Solution

  1. Step 1: Understand match and capture groups

    The match method returns a MatchData object. match[0] is the full matched string, match[1] and match[2] are the first and second capture groups.
  2. Step 2: Apply to given string and pattern

    The pattern matches "123-45" in the text. The first group captures "123", the second "45".
  3. Final Answer:

    ["123-45", "123", "45"] -> Option D
  4. Quick Check:

    Full match + groups = ["123-45", "123", "45"] [OK]
Hint: match[0] full, match[1..] capture groups [OK]
Common Mistakes:
  • Confusing full match with capture groups
  • Swapping capture group order
  • Ignoring the dash in the match
4. What is wrong with this Ruby code snippet?
text = "abc123"
match = text.match(/(\d{3})/)
puts match[1]
medium
A. It prints "123" correctly.
B. It raises an error because there is no match.
C. It prints nil without error.
D. It raises a syntax error.

Solution

  1. Step 1: Check the regex and string

    The regex /(\d{3})/ looks for exactly three digits. The string "abc123" contains "123" which matches.
  2. Step 2: Understand match and output

    The match object captures "123" in group 1. puts match[1] prints "123".
  3. Final Answer:

    It prints "123" correctly. -> Option A
  4. Quick Check:

    Digits found and printed = "123" [OK]
Hint: Check if regex matches before accessing groups [OK]
Common Mistakes:
  • Assuming no match causes error
  • Expecting nil instead of matched string
  • Confusing syntax error with runtime error
5. Given a string of dates like "2023-04-01, 2024-12-31", which Ruby code correctly extracts all year parts using capture groups?
hard
A. dates.scan(/\d{4}-\d{2}-\d{2}/)
B. dates.match(/(\d{4})-\d{2}-\d{2}/)
C. dates.scan(/(\d{4})-\d{2}-\d{2}/).flatten
D. dates.match(/\d{4}/)

Solution

  1. Step 1: Understand the goal and methods

    We want all years from multiple dates. scan finds all matches, match finds only first.
  2. Step 2: Analyze each option

    dates.scan(/(\d{4})-\d{2}-\d{2}/).flatten uses scan with a capture group for year, returning all years as array. dates.match(/(\d{4})-\d{2}-\d{2}/) uses match which returns only first match. dates.scan(/\d{4}-\d{2}-\d{2}/) uses scan but no capture group, returns full dates. dates.match(/\d{4}/) uses match without capture group, only first year.
  3. Final Answer:

    dates.scan(/(\d{4})-\d{2}-\d{2}/).flatten -> Option C
  4. Quick Check:

    scan + capture group = all years [OK]
Hint: Use scan with capture groups to get all matches [OK]
Common Mistakes:
  • Using match instead of scan for multiple matches
  • Not using capture groups to extract parts
  • Forgetting to flatten nested arrays from scan
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard