質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

6110閲覧

Javaでサロゲートペア文字を含む文字列のreplace

z_a_ki3

総合スコア30

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

1クリップ

投稿2015/07/10 09:32

サロゲートペア文字(例えば????とか????)を含む文字列でStringBufferのreplaceメソッドを
使用したいのですが、replaceメソッドはサロゲートペア文字を考慮した実装ではないようで、
意図した挙動になりません。

lang

1StringBuffer sb = new StringBuffer("????の塩焼き"); 2sb.replace(0, 1, "鮭"); 3System.out.println(sb.toString());

期待している結果

鮭の塩焼き

実際の結果

鮭?の塩焼き

だいぶ強引に実装してみたのですが、そもそも既存のAPIやライブラリがあるよとか、
もっとシンプルに実装できるよとかあれば、教えて頂きたいです。

信頼性の面で、あまり独自実装したくありません。

宜しくお願いいたします。

lang

1String replace(String source, int start, int end, String replace) { 2 3 int codePointCount = 0; 4 5 List<String> targetList = new ArrayList<String>(); 6 codePointCount = source.codePointCount(0, source.length()); 7 for(int i=0;i<=codePointCount;i=source.offsetByCodePoints(i, 1)) { 8 int[] codePoint = new int[1]; 9 codePoint[0] = source.codePointAt(i); 10 targetList.add(new String(codePoint,0,1)); 11 } 12 if(start > codePointCount) { 13 throw new IndexOutOfBoundsException("start > codePointCount()"); 14 } 15 if(end > codePointCount) { 16 end = codePointCount; 17 } 18 19 List<String> replaceList = new ArrayList<String>(); 20 codePointCount = replace.codePointCount(0, replace.length()); 21 for(int i=0;i<codePointCount;i=replace.offsetByCodePoints(i, 1)) { 22 int[] codePoint = new int[1]; 23 codePoint[0] = replace.codePointAt(i); 24 replaceList.add(new String(codePoint,0,1)); 25 } 26 27 for(int i=start;i<end;i++) { 28 targetList.remove(start); 29 } 30 31 targetList.addAll(start, replaceList); 32 33 StringBuffer result = new StringBuffer(); 34 for(String s:targetList) { 35 result.append(s); 36 } 37 38 return result.toString(); 39}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

StringBufferのoffsetByCodePoints()を活用してください。

lang

1StringBuffer sb = new StringBuffer("????の塩焼き"); 2sb.replace(0, sb.offsetByCodePoints(0,1), "鮭"); 3System.out.println(sb.toString());

投稿2015/07/10 12:01

Stripe

総合スコア2183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2015/07/10 12:03

それでできるんですね! 無駄にがんばってしまいました...
z_a_ki3

2015/07/11 06:38

単純に sb.replace( sb.offsetByCodePoints(0, start), sb.offsetByCodePoints(0, end), replaceText ); で良かったんですね…無駄なことしてました(^_^; ありがとうございます!
guest

0

Java8でも良ければ、ストリームを使って少し簡潔に書けます。

lang

1// import java.util.stream.IntStream; 2 3public static void main(String[] args) { 4 StringBuffer sb = new StringBuffer("????の塩焼き"); 5 replaceByCodePoint1(sb, 0, 1, "鮭"); 6 System.out.println(sb); // => 鮭の塩焼き 7} 8 9static void replaceByCodePoint1(StringBuffer sb, int fromIndex, int toIndex, String s) { 10 IntStream cpStream = 11 IntStream.concat(sb.codePoints().limit(fromIndex), 12 IntStream.concat(s.codePoints(), sb.codePoints().skip(toIndex))); 13 StringBuilder replaced = cpStream.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append); 14 sb.setLength(0); 15 sb.append(replaced); 16}

投稿2015/07/10 11:58

argius

総合スコア9390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

z_a_ki3

2015/07/11 06:40

ごめんなさい、Javaのランタイムのバージョン記載してませんでしたね(^_^; 今回Java8は使えないのですが、ラムダ式でコーディングするとこうなるのかと、 勉強にさせてもらいました。 ありがとうございました!
argius

2015/07/11 09:26

こちらこそすみません。StringBufferのcodePoint関連メソッドではできないと勘違いしていました。 結果、外した回答になってしまいましたが、他の何かの参考になれば幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問