こんにちは、さるまりんです。
以前、native2ascii
をJavaプログラムからやってみました。
今回はその逆です。
文字列を読み込みascii2native
をかけるメソッドです。
Ascii2Native.java
public class Ascii2Native {
public String ascii2native(String str) {
StringBuilder sb = new StringBuilder();
int len = str.length();
for (int i = 0; i < len; i++) {
char c = str.charAt(i);
if (c != '\\' || i >= len - 5) {
// この文字がバックスラッシュではない
// もしくはバックスラッシュ+5文字ではない(3文字以下)
sb.append(c);
} else {
// バックスラッシュ文字+5文字ある
char u = str.charAt(++i);
// 次の文字はu?
if (u == 'u') {
// その次の文字から4文字を16進の整数に変換
int unescaped = tryParse(str, i + 1);
// できたら
if (unescaped >= 0) {
// それを文字としてとっておき
sb.append((char) unescaped);
// インデックスを4つ進める
i += 4;
continue;
}
}
// uで始まってないのでエスケープされたものではないのでそのままとっておく
sb.append(c).append(u);
}
}
// 文字列にして戻す
return sb.toString();
}
private int tryParse(String str, int idx) {
try {
// idxで指定された箇所から4文字を16進の整数に変換
return Integer.parseInt(str.substring(idx, idx + 4), 16);
} catch (NumberFormatException ex) {
// できない場合は-1を返却
return -1;
}
}
}
プログラム内にコメントを入れていますが基本的には、文字列を1文字ずつみていき、\(バックスラッシュ)から始まれば、それが\uxxxxならば16進の整数としてとり文字に変換、それ以外はそのまま残しします。文字に変換かけられるかどうかはtryParse()メソッドでやっています。
実際に呼び出してみます。
public static void main(String[] args) {
String line = "message.greeting=\\u3053\\u3093\\u306b\\u3061\\u306f\\u3001\\u4e16\\u754c\\u3002";
System.out.println(new Ascii2Native().ascii2native(line));
}
この実行結果はこうなります。
message.greeting=こんにちは、世界。
ちゃんと必要な箇所は変換されていますね。
元のメッセージを格納しているプロパティファイルを読み込み、それと新しく作られたメッセージのテキストを読み込み、マージして新しいメッセージ一覧を作成するために、ascii2native
、マージやソートして、再度、native2ascii
するプログラムが必要でした。
ややこしい作業でもルールが決まっていることはプログラムに助けてもらう。ありがとう、プログラミングです。
読んでくださってありがとうございました。
それではまた!