是否可以使用与以下内容匹配的正则表达式匹配器:
我需要知道是否有任何子串,它们在匹配括号内部和外部,格式为(@ ... )
匹配示例:
abc (@ abc )
abc (@ (& abc ) )
abc (& def (@ abc ) )
(& (& abc def ) (@ abc ) )
(& def (& abc ) (@ abc ) )
否匹配的示例:
abc
(@ abc )
abc (@ def )
abc (& abc)
编辑: 这是检查正则表达式的rspec规范。只有2次测试失败:
“(@ abc)abc”应匹配
“(@ abc)(@ abc)”不应该匹配
describe "regex" do
let(:regex) { /(.+).*\(@.*\1.*\)/ }
matches = ["abc (@ abc )", "(@ abc ) abc", "abc (@ (& abc ) )", "abc (@ (& abc ) )"]
no_matches = ["abc", "(@ abc )", "abc def", "abc abc", "abc (& abc)", "(@ abc ) (@ abc)"]
matches.each do |flow|
it "should match '#{flow}'" do
flow.should match regex
end
end
no_matches.each do |flow|
it "should not match '#{flow}'" do
flow.should_not match regex
end
end
end
答案 0 :(得分:2)
你可以使用反向引用很容易地做到这一点:
/(.*).*\(@ \1 \)/
此处\1
是对上面未转义的括号中捕获的内容的引用。
根据引擎的不同,您的语法可能略有不同。 Perl,sed,vim等在这方面都有细微差别。例如,您可能必须逃避@
:
/(.*).*\(\@ \1 \)/
或者可能需要转义捕获括号:
/\(.*\).*(@ \1 )/
在Perl中,建议使用$1
代替\1
:
/(.*).*\(@ $1 \)/
玩它,你可能会找到正确的组合。
答案 1 :(得分:2)
答案 2 :(得分:1)
这可能会做你想要的:
(.+).*\(@.*\1.*\)
只有在(@ ...)
答案 3 :(得分:-1)
在我看来,正则表达式无法满足您的要求。您的测试看起来像是在树上执行的测试,所以您需要像解析器一样更强大的功能,它确实会将您的字符串转换为可以运行测试的树。
为此目的,请参阅ANTLR之类的解析器。还有其他,但这是我们使用的最着名的之一。
修改:正则表达式可能无法正确匹配的示例:(@ abc) (@ abc)
不匹配,但我没有看到可以将其区分为abc (@ abc)
的正则表达式匹配。