

Javaの`String.replace()`で置換した数の取得方法をインターネットやJava Docで調べているのですが、  
不明です。

長文のテキストの入った`String test;`を`test.replace("あいう", "ABC");`と実行した場合、  
何個置換を行ったかを取得したいのですが、何かの`String`のメンバー変数/関数で取得できないでしょうか？

もし、無理な場合、置換前に、for文で、`indexof("あいう", nowIndex + 1)`で数を数える方法などをするしかないでしょうか？


CC BY-SA 3.0
2016-09-05T06:25:51.887
28691
2016-09-05T13:46:13.693
2016-09-05T09:03:01.533
5519
17129
question
java
String.replace()で置換した数の取得方法


事前に(replace("あいう", "ABC")を実行する前に、testに”あいう"がいくつ含まれているかを調べるしかないと思います。  
indexofで順に調べるよりも、探す文字列("あいう")を削除(""にreplace)したら何文字消えるかを調べ、調べる文字列の文字数で割るやり方（下記コードのような感じ）が早いです。

[code]

    String test_work;
    int orig_length;
    int number_of_aiu;
    
    test_work = test.toString(); //testのコピーを作ります。
    orig_length = length(test); //testの元の文字数です。
    test_work.replace("あいう",""); //"あいう"を削除した文字列を作ります。
    number_of_aiu = (orig_length - length(test_work)/length("あいう"); // testに含まれている"あいう"の数です。
    
[/code]


CC BY-SA 3.0
2016-09-05T07:35:14.380
28693
2016-09-05T07:35:14.380
217
28691
answer


置換した数をStringのメンバー変数/関数で取得することはできませんので、他の回答にある方法やfor文、[正規表現](https://stackoverflow.com/a/12414038)などを用いて置換前に数を数えるしかありません。

もし外部のライブラリを使うことが許されるならば、Apache commons-
langの[StringUtils.countMatches](https://stackoverflow.com/a/12414152)メソッドを使うのが手っ取り早いかと思います。

※リンク先はそれぞれstack overflow英語版の回答に寄せられたサンプルコードです。


CC BY-SA 3.0
2016-09-05T08:21:49.853
28695
2016-09-05T08:21:49.853
2017-05-23T12:38:55.307
-1
9820
28691
answer


> 何かのStringのメンバー変数/関数で取得できないでしょうか？

無理だと思います。

> 無理な場合、置換前に、for文で、indexof("あいう", nowIndex + 1) で数を数える方法などをするしかないでしょうか？

`String#replace(...)`は、以下のような実装になっているので、

[code]

    public String replace(CharSequence target, CharSequence replacement) {
      return Pattern.compile(target.toString(), Pattern.LITERAL)
                    .matcher(this)
                    .replaceAll(Matcher.quoteReplacement(replacement.toString()));
    }
    
[/code]

  * [Matcher (Java Platform SE 8 )](https://docs.oracle.com/javase/jp/8/docs/api/java/util/regex/Matcher.html)
    * > 新しい文字列の内容は、必要に応じてマッチ結果から算出できます。appendReplacementおよびappendTailメソッドを同時に使用すれば、結果を収集して既存の文字列バッファに格納できます。

  * [Methods of the Matcher Class (The Java™ Tutorials > Essential Classes > Regular Expressions)](http://docs.oracle.com/javase/tutorial/essential/regex/matcher.html)

などを参考に、置換回数を数えるのが効率は良さそうです。

[code]

    import java.util.regex.Pattern;
    import java.util.regex.Matcher;
    
    public class RegexDemo {
      private static final String REGEX = "dog";
      private static final String INPUT = "dog dog dog doggie dogg";
      private static final String REPLACE = Matcher.quoteReplacement("ABC");
      public static void main(String[] args) {
        Pattern p = Pattern.compile(REGEX, Pattern.LITERAL);
        Matcher m = p.matcher(INPUT);
        int count = 0;
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
          count++;
          m.appendReplacement(sb, REPLACE);
        }
        m.appendTail(sb);
        System.out.println("count: " + count);
        System.out.println(sb.toString());
        //System.out.println(m.replaceAll(REPLACE));
      }
    }
    
[/code]


CC BY-SA 3.0
2016-09-05T08:22:48.493
28696
2016-09-05T08:31:25.317
2016-09-05T08:31:25.317
46
46
28691
answer


[split](http://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#split-
java.lang.String-int-)を使って  
置換回数:`test.split("あいう", -1).length-1`  
とするのがお手軽かもしれません。

※splitの最初の引数は正規表現文字列なので、正規表現に当たる文字などはエスケープする必要があります。


CC BY-SA 3.0
2016-09-05T13:28:03.943
28705
2016-09-05T13:46:13.693
2016-09-05T13:46:13.693
5044
5044
28691
answer