Gsub with regex in Ruby - Time & Space Complexity
When using gsub with a regular expression in Ruby, it's important to understand how the time taken grows as the input string gets longer.
We want to know how the number of operations changes when the string size increases.
Analyze the time complexity of the following code snippet.
text = "hello world hello"
pattern = /hello/
result = text.gsub(pattern, "hi")
puts result
This code replaces all occurrences of "hello" with "hi" in the given text string.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Scanning the entire string to find matches for the regex pattern.
- How many times: Each character in the string is checked once or a few times depending on the regex engine.
As the input string gets longer, the time to scan and replace grows roughly in direct proportion to the string length.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The work grows steadily as the string gets longer, roughly one check per character.
Time Complexity: O(n)
This means the time to complete the replacement grows in a straight line with the length of the input string.
[X] Wrong: "Using regex with gsub always takes the same time no matter how long the string is."
[OK] Correct: The regex engine must check each part of the string to find matches, so longer strings take more time.
Understanding how string operations like gsub scale helps you write efficient code and explain your choices clearly in interviews.
"What if the regex pattern was more complex, like including wildcards or repetitions? How would that affect the time complexity?"
Practice
gsub do when used with a regular expression?Solution
Step 1: Understand
Thegsubpurposegsubmethod is used to replace parts of a string that match a pattern.Step 2: Recognize regex usage
When used with a regex, it finds all matches and replaces them with the given replacement string.Final Answer:
It replaces all parts of the string that match the regex with a specified replacement. -> Option BQuick Check:
gsubwith regex = replace all matches [OK]
- Thinking gsub deletes the string
- Confusing gsub with split
- Assuming gsub returns string length
gsub and regex in Ruby?Solution
Step 1: Identify regex syntax in Ruby
Regex patterns in Ruby are enclosed in slashes, like/pattern/.Step 2: Match digits correctly
The regex/\d/matches any digit character. Using it withgsubreplaces all digits.Final Answer:
string.gsub(/\d/, "#") -> Option CQuick Check:
Regex in slashes + \d for digits = string.gsub(/\d/, "#") [OK]
- Using quotes instead of slashes for regex
- Using wrong regex like /d/ instead of /\d/
- Not escaping backslash properly
text = "Call me at 123-456-7890." result = text.gsub(/\d/, "*") puts result
Solution
Step 1: Understand the regex and replacement
The regex/\d/matches every digit character. The replacement is "*".Step 2: Apply
Every digit in the string is replaced by "*", so numbers become stars but other characters stay the same.gsubto replace digitsFinal Answer:
Call me at ***-***-****. -> Option AQuick Check:
Digits replaced by * = Call me at ***-***-****. [OK]
- Expecting only first digit replaced
- Confusing regex syntax causing error
- Thinking gsub changes non-digit characters
sentence = "Hello World!" sentence.gsub(/world/, "Earth")What is the problem?
Solution
Step 1: Check regex matching
The regex/world/is lowercase and Ruby regex is case-sensitive by default.Step 2: Compare with string content
The string has "World" with uppercase W, so the regex does not match anything.Final Answer:
Regex is case-sensitive, so 'world' does not match 'World'. -> Option AQuick Check:
Case sensitivity causes no match [OK]
- Assuming regex matches ignore case by default
- Thinking gsub needs parentheses around arguments
- Believing gsub can't use regex
data = "User: John_Doe, Email: john@example.com", which gsub call will replace all non-alphanumeric characters (except underscore) with a dash "-"?Solution
Step 1: Understand character classes
\wmatches letters, digits, and underscore.\Wmatches anything not in\w.Step 2: Analyze options
data.gsub(/[^a-zA-Z0-9_]/, "-"):/[^a-zA-Z0-9_]/matches non-alphanumeric except underscore - correct. data.gsub(/\w/, "-"):/\w/replaces word chars (alnum + _) - wrong. data.gsub(/[^a-zA-Z0-9]/, "-"):/[^a-zA-Z0-9]/replaces non-alnum including _ - wrong. data.gsub(/[\w]/, "-"):/[\w]/replaces word chars - wrong.Final Answer:
data.gsub(/[^a-zA-Z0-9_]/, "-") -> Option DQuick Check:
Explicit negated class for alphanumeric + underscore = data.gsub(/[^a-zA-Z0-9_]/, "-") [OK]
- Using /[^a-zA-Z0-9]/ which replaces underscores too
- Replacing word chars instead of non-word chars
- Confusing \w and \W meaning
Ready to prove it?
Pass the test and this pattern moves unknown
