2

メニューを印刷して入力などを取得するコンソールアプリがあります。メニューシステムには、下線を引いたタイトルがあります。

 Main Menu
 =========

タイトルはさまざまなサイズになる可能性があるため、最初の試みは文字列の長さを取得し、指定された下線文字の多くを印刷することでした. 残念ながら、これは日本語ロケールでは機能しません。タイトルは .properties ファイルに保存され、ResourceBundle クラスを使用してフェッチされます。

主にGUIに関連していると思われるStackOverflowでいくつかの可能な解決策を見たので、役に立ちませんでした:

public static int getGraphemeCount(String text) {
   int graphemeCount = 0;
   BreakIterator graphemeCounter = BreakIterator.getCharacterInstance();
   graphemeCounter.setText(text);
   while (graphemeCounter.next() != BreakIterator.DONE) 
      graphemeCount++;
      return graphemeCount;
}
public static void outputTitle(String title,char underChar) {
   String underline = repeats(underChar,getGraphemeCount(title));
   System.out.printf("\n\t%s\n\t%s\n",title,underline);
}

すべてのテキスト (会社名や製品名など) が翻訳されるわけではないという余分な問題があります。

[アップデート]

出力を詳しく見てみると、個々の日本語の文字が英語の文字ごとに 2 つの場所を占めているように見えます。これを文字単位で判断する機能はありますか?

[アップデート]

何かご意見は?

サイモン

4

1 に答える 1

1

端末は通常、CJK 文字を 1 つではなく 2 つのスロットを使用して表示するため、それぞれを 2 文字としてカウントする必要があります。1スロット占有する「半角文字」もあります。視覚的な文字列の長さを取得する唯一の方法は、文字をループして、全角文字を 2 文字としてカウントすることです。

文字の幅は、Unicode 文字プロパティEAST_ASIAN_WIDTHとして参照できます。残念ながら、標準 API にはこのプロパティを検索する方法がありませんが、ICU4J ライブラリには次の方法があります。

char c = ...;
int width;
switch (UCharacter.getIntPropertyValue(c, UProperty.EAST_ASIAN_WIDTH)) {
    case UCharacter.EastAsianWidth.WIDE:
    case UCharacter.EastAsianWidth.FULLWIDTH:
        width = 2; break;
    default:
        width = 1;
}

ICU4Jが使えない場合の文字データはこちら。このデータと、ブロックまたはスクリプトへの文字の割り当てとの間には、おそらく多くの重複があります。たとえば、ほとんどのHAN文字は幅が広いと思います。

于 2013-09-27T08:20:41.257 に答える