24

while(matcher.find())パターンのすべての一致をループするためにa を使用しています。matcher.group(3)見つかったパターンのインスタンスまたは一致ごとに、新しいテキストに置き換えたいと思います。このテキストはそれぞれ異なるためmatcher.appendReplacement()、元の文字列を新しい変更で再構築するために使用しています。ただし、appendReplacement()グループだけでなくパターン全体を置き換えます。

パターン全体ではなく、一致の 3 番目のグループのみを変更して、これを行うにはどうすればよいですか?

コード例を次に示します。

Pattern pattern = Pattern.compile("THE (REGEX) (EXPRESSION) (WITH MULTIPLE) GROUPS");
Matcher matcher = pattern.matcher("THE TEXT TO SEARCH AND MODIFY");
StringBuffer buffer = new StringBuffer();

while(matcher.find()){
   matcher.appendReplacement(buffer, processTheGroup(matcher.group(3));
}

しかし、私はこのようなことをしたいと思います(明らかにこれはうまくいきません)。

...
while(matcher.find()){
   matcher.group(3).appendReplacement(buffer, processTheGroup(matcher.group(3));
}

パターン全体ではなく、特定のグループのみを置き換えるようなものです。

編集:正規表現の例を変更して、すべてのパターンがグループ化されているわけではないことを示しました。

4

2 に答える 2

34

これにはすでに受け入れられた答えがあるようですが、完全には正しくありません。正解は次のようになります。

.appendReplacement("$1" + process(m.group(2)) + "$3");

これは、「$」が.appendReplacementの特殊文字であることも示しています。したがって、すべての「$」を「\ $」に置き換えるには、「process()」関数に注意する必要があります。Matcher.quoteReplacement(replacementString)がこれを行います(@Medに感謝)

グループ1または3のいずれかに「$」が含まれている場合、以前に受け入れられた回答は失敗します。「java.lang.IllegalArgumentException:Illegalgroupreference」になります。

于 2011-03-24T12:50:18.180 に答える
17

パターン全体が一致"(prefix)(infix)(suffix)"し、3 つの部分をそれぞれグループ 1、2、3 にキャプチャするとします。ここで、接頭辞と接尾辞はそのままにして、グループ 2 (インフィックス) だけを置き換えたいとしましょう。

group(1)次に、一致したもの(変更なし)、 の新しい置換group(2)、および一致したもの(変更なし)を追加します。次のgroup(3)ようになります。

matcher.appendReplacement(
    buffer,
    matcher.group(1) + processTheGroup(matcher.group(2)) + matcher.group(3)
);

これでもパターン全体が一致して置換されますが、グループ 1 と 3 は変更されないため、効果的に中置記号のみが置換されます。

特定のシナリオに同じ基本的な手法を適用できるはずです。

于 2010-10-15T07:24:15.310 に答える