Joh*_*son 9 ruby regex brackets
我试图弄清楚一个字符串是否有正确的括号.
为此,我使用以下三个支架对.
[]
()
{}
Run Code Online (Sandbox Code Playgroud)
只要格式正确,括号也可以嵌套.
)([]{} - Does not have properly closed brackets because )( is reverse order
[()] - Does contain properly closed brackets.
Run Code Online (Sandbox Code Playgroud)
我尝试过使用正则表达式,经过一些摸索后,我得到了这个.
[^\(\[]*(\(.*\))[^\)\]]*
Run Code Online (Sandbox Code Playgroud)
但是,这有一些问题.
它只匹配括号但不匹配括号
我不明白为什么它与括号不匹配.
在我的例子中,我清楚地在括号前使用了反斜杠.
输入
[] - true
[()] - true (nested brackets but they match properly)
{} - true
}{ - false (brackets are wrong direction)
}[]} - false (brackets are wrong direction)
[[]] - true (nested brackets but they match properly
Run Code Online (Sandbox Code Playgroud)
non_delimiters = /[^(){}\[\]]*/
Paired = /\(#{non_delimiters}\)|\{#{non_delimiters}\}|\[#{non_delimiters}\]/
Delimiter = /[(){}\[\]]/
def balanced? s
s = s.dup
s.gsub!(Paired, "".freeze) while s =~ Paired
s !~ Delimiter
end
balanced?(")([]{}")
# => false
balanced?("[]")
# => true
balanced?("[()]")
# => true
balanced?("{}")
# => true
balanced?("}{")
# => false
balanced?("}[]}")
# => false
balanced?("[[]]")
# => true
Run Code Online (Sandbox Code Playgroud)
这可能是一个正则表达式的坏用例,我会使用一个简单的堆栈解析器.
def matching_brackets?(a_string)
brackets = {'[' => ']', '{' => '}', '(' => ')'}
lefts = brackets.keys
rights = brackets.values
stack = []
a_string.each_char do |c|
if lefts.include? c
stack.push c
elsif rights.include? c
return false if stack.empty?
return false unless brackets[stack.pop].eql? c
end
end
stack.empty?
end
matching_brackets? "[]"
matching_brackets? "[()]"
matching_brackets? "{}"
matching_brackets? "}{"
matching_brackets? "}[]}"
matching_brackets? "[[]]"
matching_brackets? "[[{]}]"
Run Code Online (Sandbox Code Playgroud)
编辑:Cary Swoveland - 写实际代码并让人们批评它: - ?
更新:我的检查中有一个讨厌的小虫子,看看结束的角色是否与开头的角色相匹配.固定它!
根据这篇文章,2.0版本的Ruby支持递归regexp.这意味着您可以使用特定\g<0>于Ruby的令牌在正则表达式的任何位置递归匹配整个正则表达式.这种方法可以有效地模拟堆栈以解决您的任务.
这是由此产生的正则表达式:
[^(){}\[\]]*(\((\g<0>)?\)|\{(\g<0>)?\}|\[(\g<0>)?\])?[^(){}\[\]]*
此更新版本处理如下情况:[(){}]当多个括号组处于同一级别时.感谢@Jonny 5指出这个案例:
[^(){}\[\]]*((\((\g<0>)?\)|\{(\g<0>)?\}|\[(\g<0>)?\])?[^(){}\[\]]*)*
Run Code Online (Sandbox Code Playgroud)
此表达式需要检查整个输入字符串是否匹配.部分匹配意味着在字符串的某个点处括号排序中存在错误.
这是其他版本,不需要检查整个输入字符串是否匹配:
\A([^(){}\[\]]*((\((\g<1>)?\)|\{(\g<1>)?\}|\[(\g<1>)?\])?[^(){}\[\]]*)*)\Z
Run Code Online (Sandbox Code Playgroud)
您可能会注意到它尝试匹配相应的括号对,然后递归匹配自身.我在这里尝试了它似乎工作.我不是Ruby工程师所以我不能运行实际的Ruby测试,但希望它没有必要.