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のようなパーサーを参照してください。他にもありますが、これは私たちが使用する最も有名なものの1つです。

編集:正規表現によって正しく一致しない可能性のある例:一致しない(@ abc) (@ abc)はずですが、一致するものと区別できる正規表現が表示されませんabc (@ abc)

于 2012-09-04T10:30:40.880 に答える