1

"Hello <a1> sqjsjqk <b1,b2> dsjkfjkdsf <c1,c2,c3> ffsd"例のように、文字列内の <> 間のコンマ区切りの単語のリストの一致を見つけるために使用する正規表現があります。

中括弧の間に各単語を保持するために、キャプチャ グループを使用したいと考えています。

これが私の表現です: < (\w+) (?: ,(\w+) )* >(読みやすくするためにスペースが追加されていますが、パターンの一部ではありません)

括弧はキャプチャ グループを(?: )作成するためのもので、非キャプチャ グループを作成するためのものです。コマを保持したくないからです。

ここに私のテストコードがあります:

@Test
public void test() {
    String patternString = "<(\\w+)(?:,(\\w+))*>";
    Pattern pattern = Pattern.compile(patternString);
    Matcher matcher = pattern.matcher("Hello <a1> sqjsjqk <b1,b2> dsjkfjkdsf <c1,c2,c3> ffsd");
    while(matcher.find()) {
        System.out.println("== Match ==");
        MatchResult matchResult = matcher.toMatchResult();
        for(int i = 0; i < matchResult.groupCount(); i++) {
            System.out.println("  " + matchResult.group(i + 1));
        }
    }
}

これは、生成される出力です。

== Match ==
  a1
  null
== Match ==
  b1
  b2
== Match ==
  c1
  c3

そして、ここに私が欲しかったものがあります:

== Match ==
  a1
== Match ==
  b1
  b2
== Match ==
  c1
  c2
  c3

このことから、式のキャプチャ グループの数とまったく同じ数のグループがあることがわかりますが、これは私が望むものではありません。 \w+

単一の RegExp で必要なものを取得する機会はありますか、または 、 などで仕事を終了する必要がありsplit(",")ますtrim()...

4

1 に答える 1

2

私の知る限り、単一のキャプチャ グループに対して複数のキャプチャを返すことができる正規表現エンジンは .NET だけです。したがって、あなたが求めていることはJavaでは不可能です(少なくともあなたが求めた方法ではありません)。

ただし、あなたの場合、この問題はある程度解決できます。不一致の終了が決してないことが確実な場合は>、完全な一致をキャプチャしたいものを作成し、先読みを通じて正しい位置を要求できます。

"\\w+(?=(?:,\\w+)*>)"

これは、 の外側の「単語」と一致することはありません。これは、開始を通過して終了と一致する<...>ことができないためです。もちろん、これにより、異なるセットの要素を区別することが難しくなります。<><...>

別の方法として (そして、より安全で読みやすいので、その方が良いと思います)、2 段階のアルゴリズムを使用します。最初の試合

"<([\\w,]*)>"

次にsplit、 でのすべての結果の最初のキャプチャ,

于 2012-11-16T20:25:10.470 に答える