4

是否有可能有一个匹配以下内容的正则表达式匹配器:我需要知道是否有任何子字符串在匹配括号的内部和外部,完全格式化为(@ ... )

匹配示例:

  • 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

4 回答 4

2

尝试使用正则表达式模式

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

请参阅此测试代码

于 2012-09-04T13:07:55.580 回答
2

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

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

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

您的语法可能会因引擎而略有不同。Perl、sed、vim 等在这方面都有细微的差别。例如,您可能必须转义@

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

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

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

在 Perl 中,建议使用$1而不是\1

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

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

于 2012-09-04T10:23:33.440 回答
1

这可能会做你想做的事:

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

只有当某些字符串在外部和内部都存在时才会匹配(@ ...)

于 2012-09-04T10:21:54.810 回答
-1

在我看来,正则表达式无法满足您的要求。您的测试看起来像是在树上执行的测试,因此您需要更强大的东西,例如解析器,它确实会将您的字符串变成可以在其上运行测试的树。

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

编辑:正则表达式可能无法正确匹配的示例:不(@ abc) (@ abc)应该匹配,但我没有看到可以将其与abc (@ abc)匹配项区分开来的正则表达式。

于 2012-09-04T10:30:40.880 回答