Mar 19, 2006
Normalizer にチャレンジ
Normalizer とは
java.text.Normalize は Mustang から導入された文字列処理用のクラス。 Unicode 文字列の正規化を行ってくれる。 今まで独自のコードでやっていた処理を Normalizer に置き換えられそうなのでチェックしてみた。
- Class Normalizer
- http://download.java.net/jdk6/doc/api/java/text/Normalizer.html
- Enum Normalizer.Form
- http://download.java.net/jdk6/doc/api/java/text/Normalizer.Form.html
- Normalization Charts
- http://www.unicode.org/charts/normalization/
Normalizer では、以下の 4 つの Normalization Form が定義されている。
- NFC - Canonical decomposition, followed by canonical composition.
- NFD - Canonical decomposition.
- NFKC - Compatibility decomposition, followed by canonical composition.
- NFKD - Compatibility decomposition.
変換結果
日本語を使用するアプリケーションで頻繁に変換処理が行われる文字をチェックしてみた。 NFKC 変換が現在の独自ロジックでの変換の置き換えに使用できそう。 但し、色々試してみたところ多少不足があるので単純な置き換えは無理。
ORIGINAL -> NFC NFD NFKC NFKD ------------------------------------------------------------- ¢ (00A2) -> ¢ (00A2) ¢ (00A2) ¢ (00A2) ¢ (00A2) ¢ (FFE0) -> ¢ (FFE0) ¢ (FFE0) ¢ (00A2) ¢ (00A2) £ (00A3) -> £ (00A3) £ (00A3) £ (00A3) £ (00A3) £ (FFE1) -> £ (FFE1) £ (FFE1) £ (00A3) £ (00A3) ¬ (00AC) -> ¬ (00AC) ¬ (00AC) ¬ (00AC) ¬ (00AC) ¬ (FFE2) -> ¬ (FFE2) ¬ (FFE2) ¬ (00AC) ¬ (00AC) - (002D) -> - (002D) - (002D) - (002D) - (002D) - (FF0D) -> - (FF0D) - (FF0D) - (002D) - (002D) | (007C) -> | (007C) | (007C) | (007C) | (007C) | (FF5C) -> | (FF5C) | (FF5C) | (007C) | (007C) ~ (007E) -> ~ (007E) ~ (007E) ~ (007E) ~ (007E) ~ (FF5E) -> ~ (FF5E) ~ (FF5E) ~ (007E) ~ (007E) が (304C) -> が (304C) か? (304B3099) が (304C) か? (304B3099) ぎ (304E) -> ぎ (304E) き? (304D3099) ぎ (304E) き? (304D3099) ぱ (3071) -> ぱ (3071) は? (306F309A) ぱ (3071) は? (306F309A) ぴ (3074) -> ぴ (3074) ひ? (3072309A) ぴ (3074) ひ? (3072309A) ㍉ (3349) -> ㍉ (3349) ㍉ (3349) ミリ (30DF30EA) ミリ (30DF30EA) ㌔ (3314) -> ㌔ (3314) ㌔ (3314) キロ (30AD30ED) キロ (30AD30ED) ㎜ (339C) -> ㎜ (339C) ㎜ (339C) mm (006D006D) mm (006D006D) ㎡ (33A1) -> ㎡ (33A1) ㎡ (33A1) m2 (006D0032) m2 (006D0032) ㍻ (337B) -> ㍻ (337B) ㍻ (337B) 平成 (5E736210) 平成 (5E736210) ㍼ (337C) -> ㍼ (337C) ㍼ (337C) 昭和 (662D548C) 昭和 (662D548C) № (2116) -> № (2116) № (2116) No (004E006F) No (004E006F) ㏍ (33CD) -> ㏍ (33CD) ㏍ (33CD) KK (004B004B) KK (004B004B) ℡ (2121) -> ℡ (2121) ℡ (2121) TEL (00540045004C) TEL (00540045004C) ㊤ (32A4) -> ㊤ (32A4) ㊤ (32A4) 上 (4E0A) 上 (4E0A) ㊥ (32A5) -> ㊥ (32A5) ㊥ (32A5) 中 (4E2D) 中 (4E2D) ㈱ (3231) -> ㈱ (3231) ㈱ (3231) (株) (0028682A0029) (株) (0028682A0029) ㈲ (3232) -> ㈲ (3232) ㈲ (3232) (有) (002867090029) (有) (002867090029)
サンプルコード
package jp.in_vitro.codelets.text;
import java.text.Normalizer;
public class Codelet {
public Codelet() {
super();
}
public static void main(String[] args) {
Codelet me = new Codelet();
me.execute();
}
protected void execute() {
String targets = "\u00A2\uFFE0\u00A3\uFFE1\u00AC\uFFE2\u002D\uFF0D\u007C\uFF5C\u007E\uFF5Eがぎぱぴ㍉㌔㎜㎡㍻㍼№㏍℡㊤㊥㈱㈲";
System.out
.println("ORIGINAL -> NFC NFD NFKC NFKD");
System.out
.println("-------------------------------------------------------------");
for (char ch : targets.toCharArray()) {
this.normalize("" + ch);
}
}
protected void normalize(final String target) {
String normalized = null;
String normalizedHex = null;
System.out.print("" + target + " (" + this.toHex(target) + ") -> ");
normalized = Normalizer.normalize(target, Normalizer.Form.NFC);
normalizedHex = this.toHex(normalized);
System.out.print(" " + normalized + " (" + normalizedHex + ")");
normalized = Normalizer.normalize(target, Normalizer.Form.NFD);
normalizedHex = this.toHex(normalized);
System.out.print(" " + normalized + " (" + normalizedHex + ")");
normalized = Normalizer.normalize(target, Normalizer.Form.NFKC);
normalizedHex = this.toHex(normalized);
System.out.print(" " + normalized + " (" + normalizedHex + ")");
normalized = Normalizer.normalize(target, Normalizer.Form.NFKD);
normalizedHex = this.toHex(normalized);
System.out.print(" " + normalized + " (" + normalizedHex + ")");
System.out.println();
}
protected String toHex(final String str) {
StringBuffer buf = new StringBuffer();
for (char ch : str.toCharArray()) {
buf.append(Integer.toString((int) ((ch >> 12) & 0x0F), 16)
.toUpperCase());
buf.append(Integer.toString((int) ((ch >> 8) & 0x0F), 16)
.toUpperCase());
buf.append(Integer.toString((int) ((ch >> 4) & 0x0F), 16)
.toUpperCase());
buf.append(Integer.toString((int) (ch & 0x0F), 16).toUpperCase());
}
return new String(buf);
}
}
TrackBack ping me at
http://www.in-vitro.jp/blog/index.cgi/Mustang/20060319_01.trackback
writeback message: Ready to post a comment.
