I have:
str ="this is the string "
and I have an array of strings:
array =["this is" ,"second element", "third element"]
I want to process the string such that substring matching any of the element of the array should be removed and rest of the string should be returned. I want the following output:
output: "the string "
How can i do this?.
You don't say whether you want true substring matching, or substring matching at word-boundaries. There's a difference. Here's how to do it honoring word boundaries:
str = "this is the string "
array = ["this is" ,"second element", "third element"]
pattern = /\b(?:#{ Regexp.union(array).source })\b/ # => /\b(?:this\ is|second\ element|third\ element)\b/
str[pattern] # => "this is"
str.gsub(pattern, '').squeeze(' ').strip # => "the string"
Here's what's happening with union and union.source:
Regexp.union(array) # => /this\ is|second\ element|third\ element/
Regexp.union(array).source # => "this\\ is|second\\ element|third\\ element"
source returns the joined array in a form that can be more easily consumed by Regex when creating a pattern, without it injecting holes into the pattern. Consider these differences and what they could do in a pattern match:
/#{ Regexp.union(%w[a . b]) }/ # => /(?-mix:a|\.|b)/
/#{ Regexp.union(%w[a . b]).source }/ # => /a|\.|b/
The first creates a separate pattern, with its own flags for case, multiple-line and white-space honoring, that would be embedded inside the outer pattern. That can be a bug that's really hard to track down and fix, so only do it when you intend to have the sub-pattern.
Also, notice what happens if you try to use:
/#{ %w[a . b].join('|') }/ # => /a|.|b/
The resulting pattern has a wildcard . embedded in it, which would blow apart your pattern, causing it to match anything. Don't go there.
If we don't tell the regex engine to honor word boundaries then unexpected/undesirable/terrible things can happen:
str = "this isn't the string "
array = ["this is" ,"second element", "third element"]
pattern = /(?:#{ Regexp.union(array).source })/ # => /(?:this\ is|second\ element|third\ element)/
str[pattern] # => "this is"
str.gsub(pattern, '').squeeze(' ').strip # => "n't the string"
It's important to think in terms of words, when working with substrings containing complete words. The engine doesn't know the difference, so you have to tell it what to do. This is a situation missed all too often by people who haven't had to do text processing.
Here is one way -
array =["this is" ,"second element", "third element"]
str = "this is the string "
str.gsub(Regexp.union(array),'') # => " the string "
To allow case-insensitive - str.gsub(/#{array.join('|')}/i,'')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With