Aufheben - GLAD!! の日記 このページをアンテナに追加

2005 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 |
2010 | 02 | 07 |
2011 | 01 | 02 |
2013 | 01 |
2015 | 07 | 08 |
2016 | 02 |

2016-02-17 (水)

[] Windows-31JJIS X 0213 の共用 00:59  Windows-31J と JIS X 0213 の共用を含むブックマーク

文字コードに関する昨日のつぶやき

これを図で表してみました。

x-MS932_0213 は第3水準漢字に使える文字と使えない文字があり中途半端。「NEC選定IBM拡張漢字」は「IBM拡張漢字」と重複しているから、領域を丸ごと第3水準漢字に明け渡して、いちばん右の文字セットを使うというのが、個人的にはいい案だと思うんですけどね。

2面は、第4水準漢字を使うより「IBM拡張漢字」と「ユーザー定義外字」を残した方が、互換性と拡張性の点でベターな気がします。JIS X 0213 推進者の人からは怒られそうですが…。

トラックバック - http://d.hatena.ne.jp/aufheben/20160217

2015-08-31 (月)

[Tech] ローカルファイルのタイムスタンプSVNコミット時刻にする 00:53  [Tech] ローカルファイルのタイムスタンプを SVN のコミット時刻にするを含むブックマーク

お客様先で SVN を導入したんだけど、既存ファイルのタイムスタンプを保持したいという要望が多かったので、ローカルファイルのタイムスタンプコミット日時にするスクリプトを書いてみた。

実行前に、リポジトリの pre-revprop-change を変更して、リビジョンプロパティの変更を許可する必要があります。

あと、TortoiseSVN の「ファイルの更新日時を『最終コミット日時』に設定する」にチェックを入れておくと、チェックアウトしたときにファイルのタイムスタンプコミット日時になります。

https://gist.github.com/glad2121/f11d42b0a7a5735bead9

トラックバック - http://d.hatena.ne.jp/aufheben/20150831

2015-08-30 (日)

[Java][文字コード] Unicode 正規化と、文字列正規表現関数を用いた置換 17:56  [Java][文字コード] Unicode 正規化と、文字列の正規表現と関数を用いた置換を含むブックマーク

Java の標準ライブラリjava.text.Normalizer という Unicode 正規化を行うクラスがあります。

濁点・半濁点を合成・分解したりするのに便利なのですが、JIS X 0208 の「Å(U+212B)」を「上リング付きA(U+00C5)」に変換したり、JIS X 0213ギリシャ文字のαやεにアクセントが付いた U+1F71、U+1F73 を U+03AC、U+03AD に変換するなど、余計な変換を行うため、JIS のコードに戻せなくなってしまいます。

そこで、ひらがな・カタカナだけを正規化することができないか考えてみました。

正規表現でひらがな・カタカナを検索し、マッチした文字列だけ正規化します。

最初、合成と分解をそれぞれ実装したのですが、同じようなロジックになったので、Java8 の関数を用いて共通化してみました。

まず、文字列正規表現で検索し、マッチした文字列を変換するメソッドを作成します。

/**
 * 文字列に含まれるパターンを関数を使って置換します。
 *
 * @param s 文字列
 * @param p パターン
 * @param f 関数
 * @return 変換後の文字列
 */
static String replaceAll(
        CharSequence s, Pattern p, Function<String, String> f) {
    Matcher m = p.matcher(s);
    int length = s.length();
    StringBuilder sb = new StringBuilder(length);
    int index = 0;
    while (m.find()) {
        // マッチしなかった部分をそのまま追加。
        sb.append(s.subSequence(index, m.start()));
        // マッチした部分を変換して追加。
        sb.append(f.apply(m.group()));
        index = m.end();
    }
    // 残りをそのまま追加。
    sb.append(s.subSequence(index, length));
    return sb.toString();
}

これを使えば、濁点・半濁点の合成・分解のコードは簡単に実装できました。

/**
 * 全角カナの正規表現。
 */
static final Pattern FULLWIDTH_KANA =
        Pattern.compile("[\u3041-\u309A\u30A1-\u30FA]+");

/**
 * 文字列に含まれる基底文字と結合文字を合成します。
 *
 * @param s 文字列
 * @return 合成された文字列
 */
static String composeFullwidthKana(CharSequence s) {
    return replaceAll(s, FULLWIDTH_KANA,
            (g) -> Normalizer.normalize(g, Normalizer.Form.NFC));
}

/**
 * 文字列に含まれる合成済み文字を基底文字と結合文字に分解します。
 *
 * @param s 文字列
 * @return 分解された文字列
 */
static String decomposeFullwidthKana(CharSequence s) {
    return replaceAll(s, FULLWIDTH_KANA,
            (g) -> Normalizer.normalize(g, Normalizer.Form.NFD));
}
トラックバック - http://d.hatena.ne.jp/aufheben/20150830

2015-08-29 (土)

[Java][文字コード] Java8 の非互換な文字コード変換 12:32  [Java][文字コード] Java8 の非互換な文字コード変換を含むブックマーク

文字コード関連でちょっと調べていたら、未定義文字を変換したときの挙動が Java8 と Java7 までで異なることを発見したのでメモ。

Java7 まではネイティブコードの1文字が概ね U+FFFD 1つに変換される。

# 半角の未定義文字
1B284920 -> FF60 (ISO-2022-JP)
8EA0 -> FFFD (EUC-JP)
A0 -> FFFD (Shift_JIS)
A0 -> FFFD (windows-31j)
A0 -> FFFD (x-SJIS_0213)
# 半角の定義文字(参考)
1B284921 -> FF61 (ISO-2022-JP)
8EA1 -> FF61 (EUC-JP)
A1 -> FF61 (Shift_JIS)
A1 -> FF61 (windows-31j)
A1 -> FF61 (x-SJIS_0213)
# 全角の範囲外領域
1B24422120 -> FFFD (ISO-2022-JP)
A1A0 -> FFFD (EUC-JP)
813F -> FFFD (Shift_JIS)
813F -> FFFD (windows-31j)
813F -> FFFD003F (x-SJIS_0213)
# 全角の定義文字(参考)
1B24422121 -> 3000 (ISO-2022-JP)
A1A1 -> 3000 (EUC-JP)
8140 -> 3000 (Shift_JIS)
8140 -> 3000 (windows-31j)
8140 -> 3000 (x-SJIS_0213)
# 全角の未定義文字
1B24422271 -> FFFD (ISO-2022-JP)
A2F1 -> FFFD (EUC-JP)
81EF -> FFFD (Shift_JIS)
81EF -> FFFD (windows-31j)
81EF -> 2194 (x-SJIS_0213)
# 全角の未定義文字
1B24422321 -> FFFD (ISO-2022-JP)
A3A1 -> FFFD (EUC-JP)
8240 -> FFFD (Shift_JIS)
8240 -> FFFD (windows-31j)
8240 -> 25B7 (x-SJIS_0213)
# 全角の未定義文字
1B2442247E -> FFFD (ISO-2022-JP)
A4FE -> FFFD (EUC-JP)
82FC -> FFFD (Shift_JIS)
82FC -> FFFD (windows-31j)
82FC -> FFFD (x-SJIS_0213)

# ISO-2022-JP の最初の変換はバグっぽいですが。

ところが、Java8 だと U+FFFD が1つだったり2つだったり、2バイト目が有効な文字だったら変換されたりと安定しない。

# 半角の未定義文字
1B284920 -> FF60 (ISO-2022-JP)
8EA0 -> FFFD (EUC-JP)
A0 -> FFFD (Shift_JIS)
A0 -> FFFD (windows-31j)
A0 -> FFFD (x-SJIS_0213)
# 半角の定義文字(参考)
1B284921 -> FF61 (ISO-2022-JP)
8EA1 -> FF61 (EUC-JP)
A1 -> FF61 (Shift_JIS)
A1 -> FF61 (windows-31j)
A1 -> FF61 (x-SJIS_0213)
# 全角の範囲外領域
1B24422120 -> FFFD (ISO-2022-JP)
A1A0 -> FFFD (EUC-JP)
813F -> FFFD003F (Shift_JIS)
813F -> FFFD003F (windows-31j)
813F -> FFFD003F (x-SJIS_0213)
# 全角の定義文字(参考)
1B24422121 -> 3000 (ISO-2022-JP)
A1A1 -> 3000 (EUC-JP)
8140 -> 3000 (Shift_JIS)
8140 -> 3000 (windows-31j)
8140 -> 3000 (x-SJIS_0213)
# 全角の未定義文字
1B24422271 -> FFFD (ISO-2022-JP)
A2F1 -> FFFD (EUC-JP)
81EF -> FFFD (Shift_JIS)
81EF -> FFFD (windows-31j)
81EF -> 2194 (x-SJIS_0213)
# 全角の未定義文字
1B24422321 -> FFFD (ISO-2022-JP)
A3A1 -> FFFD (EUC-JP)
8240 -> FFFD0040 (Shift_JIS)
8240 -> FFFD0040 (windows-31j)
8240 -> 25B7 (x-SJIS_0213)
# 全角の未定義文字
1B2442247E -> FFFD (ISO-2022-JP)
A4FE -> FFFD (EUC-JP)
82FC -> FFFD (Shift_JIS)
82FC -> FFFDFFFD (windows-31j)
82FC -> FFFD (x-SJIS_0213)

未定義文字なので大きな問題にはならないかもしれないけれど、こういう非互換は勘弁してほしいなぁ…。

参考までに、チェックに使った環境とソースコードは以下の通り。

続きを読む

トラックバック - http://d.hatena.ne.jp/aufheben/20150829

2015-07-31 (金)

[DDD] 酔っぱらいの戯れ言 01:39  [DDD] 酔っぱらいの戯れ言を含むブックマーク

Eric Evans の Domain-Driven Design

エリック・エヴァンスのドメイン駆動設計

エリック・エヴァンスのドメイン駆動設計

は、アーキテクチャの本であって、ドメイン分析の本じゃない。

本当に DDD やりたいなら、以下の本も読むべし。

  • Coad「カラーUML

  • Hruby「ビジネスパターンによるモデル駆動設計」

T字形ER データベース設計技法

T字形ER データベース設計技法

  • ドメイン分析で重要なのは、Entity と Value の識別じゃなくて、Entity の深掘り。
  • Fowler の Service Layer は重要な概念だったのに、Evans がその他オブジェクトに Service って名前をつけたのは犯罪的。
  • 同じく、Evans の Value は Fowler の言う Value じゃなく、単なるデータクラス。
  • ピュアなオブジェクト指向の「もの(マスター系)」偏重、「こと(イベント系)」は関連で表すはダメ。「こと」があってこそ「もの」の要件が決まる。どちらもオブジェクトにすべき。
  • とは言え、ドメインによっては、Value が Entity になったり、「もの」が「こと」になることも。
  • 「知識レベル」「操作レベル」と「もの」「こと」は直交する。「ものの知識レベル」も「ことの知識レベル」もある。

そんなわけで、DDD は必要だと思うけど、Evans の DDD はどうも好きになれない。

(by Fowler まんせーおじさん)

なんか昔も同じような話書いてた。(^^;)

http://d.hatena.ne.jp/aufheben/20090501

トラックバック - http://d.hatena.ne.jp/aufheben/20150731