Named captures in Ruby - Time & Space Complexity
We want to understand how the time it takes to find named parts in text grows as the text gets longer.
How does the work change when we use named captures in Ruby regular expressions?
Analyze the time complexity of the following code snippet.
text = "Name: John, Age: 30; Name: Jane, Age: 25"
pattern = /Name: (?\w+), Age: (?\d+)/
text.scan(pattern) do
name = Regexp.last_match[:name]
age = Regexp.last_match[:age]
# process name and age
end
This code finds all name and age pairs in a string using named captures in a regular expression.
- Primary operation: The scan method loops through the text to find matches.
- How many times: It runs once for each match found in the text.
As the text gets longer, the number of matches usually grows too, so the work grows with the text size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks for matches |
| 100 | About 100 checks for matches |
| 1000 | About 1000 checks for matches |
Pattern observation: The work grows roughly in direct proportion to the length of the text.
Time Complexity: O(n)
This means the time to find named captures grows linearly as the text gets longer.
[X] Wrong: "Using named captures makes the search slower by a lot."
[OK] Correct: Named captures add only a small, constant amount of work per match, so the overall time still grows mainly with the text size.
Understanding how pattern matching scales helps you write efficient text processing code, a useful skill in many programming tasks.
"What if we changed the pattern to use unnamed captures instead? How would the time complexity change?"
Practice
/(?<name>pattern)/Solution
Step 1: Understand named capture syntax
The syntax?<name>inside parentheses names the capture group.Step 2: Purpose of named captures
This lets you access matched parts by name instead of number, making code clearer.Final Answer:
Labels a part of the matched text with a name for easy access -> Option CQuick Check:
Named capture = label matched text [OK]
- Confusing named captures with regex flags
- Thinking named captures repeat patterns
- Assuming named captures only match digits
Solution
Step 1: Recall named capture syntax
Named captures use?<name>inside parentheses to name the group.Step 2: Check each option
/(?<year>\d{4})/ correctly uses(?<year>\d{4}). Others miss brackets or have wrong syntax.Final Answer:
/(?<year>\d{4})/ is correct syntax -> Option DQuick Check:
Correct syntax = (?<name>) [OK]
- Omitting angle brackets around the name
- Placing name outside parentheses
- Using wrong brackets or missing parentheses
text = "Date: 2024-06-15"
regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
m = text.match(regex)
puts "Year: #{m[:year]}, Month: #{m[:month]}, Day: #{m[:day]}"Solution
Step 1: Match regex with named captures
The regex captures year, month, and day parts from the text "Date: 2024-06-15".Step 2: Access named captures from match object
Usingm[:year],m[:month], andm[:day]returns "2024", "06", and "15" respectively.Final Answer:
Year: 2024, Month: 06, Day: 15 -> Option AQuick Check:
Named captures return parts by name [OK]
- Using m['name'] instead of m[:name]
- Forgetting to call match before accessing captures
- Expecting full match instead of named parts
text = "User: alice, Age: 30"
regex = /User: (?<name>\w+), Age: (?<age>\d+)/
m = regex.match(text)
puts "Name: #{m['name']}, Age: #{m['age']}"Solution
Step 1: Check how named captures are accessed
Named captures in Ruby match objects are accessed with symbols, likem[:name], not strings.Step 2: Identify the error in code
The code usesm['name']andm['age'], which causes a nil result or error.Final Answer:
Using string keys instead of symbols to access named captures -> Option BQuick Check:
Use symbols, not strings, for named captures [OK]
- Using string keys instead of symbols
- Confusing match method call on regex vs string
- Missing parentheses in regex groups
"Order #1234: 5 items, total $99.95"Write a Ruby regex with named captures to extract order number, item count, and total price.
Which regex correctly captures these parts?
Solution
Step 1: Analyze the text format
The text is "Order #1234: 5 items, total $99.95" with colon and comma exactly as shown.Step 2: Match regex parts carefully
/Order #(?<order_num>\d+): (?<items>\d+) items, total \$(?<total>\d+\.\d{2})/ matches colon after order number, space, number of items, comma, space, "total $", and price with two decimals.Step 3: Check other options
Options A and C miss the comma or colon or both, and /Order #(?<order_num>\d+): (?<items>\d+) items, total \$(?<total>\d+\.\d{3})/ expects three decimals instead of two.Final Answer:
/Order #(?<order_num>\d+): (?<items>\d+) items, total \$(?<total>\d+\.\d{2})/ -> Option AQuick Check:
Match exact punctuation and decimal places [OK]
- Missing colon or comma in pattern
- Wrong decimal places in price capture
- Using incorrect group names or syntax
Ready to prove it?
Pass the test and this pattern moves unknown
