正则表达式可以实现吗?

时间:2012-09-04 10:19:40

标签: regex

是否可以使用与以下内容匹配的正则表达式匹配器: 我需要知道是否有任何子串,它们在匹配括号内部和外部,格式为(@ ... )

匹配示例:

  • 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

4 个答案:

答案 0 :(得分:2)

你可以使用反向引用很容易地做到这一点:

/(.*).*\(@ \1 \)/

此处\1是对上面未转义的括号中捕获的内容的引用。

根据引擎的不同,您的语法可能略有不同。 Perl,sed,vim等在这方面都有细微差别。例如,您可能必须逃避@

/(.*).*\(\@ \1 \)/

或者可能需要转义捕获括号:

/\(.*\).*(@ \1 )/

在Perl中,建议使用$1代替\1

/(.*).*\(@ $1 \)/

玩它,你可能会找到正确的组合。

答案 1 :(得分:2)

尝试使用正则表达式

/(?=.*?(?<!@ )(\b\w+\b)).*\(@.*\1.*\)/

请参阅this test code

答案 2 :(得分:1)

这可能会做你想要的:

(.+).*\(@.*\1.*\)

只有在(@ ...)

的外部和内部存在某些字符串时,它才会匹配

答案 3 :(得分:-1)

在我看来,正则表达式无法满足您的要求。您的测试看起来像是在树上执行的测试,所以您需要像解析器一样更强大的功能,它确实会将您的字符串转换为可以运行测试的树。

为此目的,请参阅ANTLR之类的解析器。还有其他,但这是我们使用的最着名的之一。

修改:正则表达式可能无法正确匹配的示例:(@ abc) (@ abc)不匹配,但我没有看到可以将其区分为abc (@ abc)的正则表达式匹配。