I am not great with regular expressions. I am looking to find if a string contains \"( ),[ ], { }\". Note, I am not looking for the contents in the actual ( ), just to see if
If you want to check for matching parens / brackets / braces, this will work:
/\(.*\)|\{.*\}|\[.*\]/
see here for more.
And this returns the matching portions of your string:
>> "alkd(jfla)kjd{adlkfj}alkjfd".scan(/\(.*\)|\{.*\}|\[.*\]/)
=> ["(jfla)", "{adlkfj}"]
Use alternatives with a non-greedy match:
/\(.*?\)|\{.*?\}|\[.*?\]/
Without those question marks, the patterns .*
would be "greedy", eg scanning "abc(def)ehi(jkl)mno" would find only one match of "(def)ehi(jkl)" (the .*
would gobble up everything to the last close bracket), but using non-greedy .*?
you would get two matches "(def)" and "(jkl)" as you would want.
You said (in a comment) that you want to validate matching parentheses. However, "())("
contains two pairs of one open and one closed parentheses, but they are not matching.
To confirm the string contains at least one pair of matching parentheses, braces or brackets, and no non-matching pairs, you can use a stack.
def check_it(str)
h = { '(' => ')', '{' => '}', '[' => ']' }
hi = h.invert
at_least_one_pair = false
stack = []
str.each_char do |c|
if h.key?(c)
stack << c
at_least_one_pair = true
elsif hi.key?(c)
return false unless stack.last == hi[c]
stack.pop
end
end
stack.empty? && at_least_one_pair
end
check_it "who (is) {that} at the {door}?" #=> true
check_it "who (is{ [that at] the} door)?" #=> true
check_it "who (is) )that( at the door?" #=> false
check_it "who (is[ )that] at the door?" #=> false
check_it "who (is that at the door?" #=> false
check_it "who is that at the door" #=> false