何となく Blog by Jitta
Microsoft .NET 考

目次

Blog 利用状況
  • 投稿数 - 761
  • 記事 - 18
  • コメント - 35955
  • トラックバック - 222
ニュース
  • IE7以前では、表示がおかしい。div の解釈に問題があるようだ。
    IE8の場合は、「互換」表示を OFF にしてください。
  • 検索エンジンで来られた方へ:
    お望みの情報は見つかりましたか? よろしければ、コメント欄にどのような情報を探していたのか、ご記入ください。
It's ME!
  • はなおか じった
  • 世界遺産の近くに住んでます。
  • Microsoft MVP for Visual Developer ASP/ASP.NET 10, 2004 - 9, 2011
広告

記事カテゴリ

書庫

日記カテゴリ

ギャラリ

その他

わんくま同盟

同郷

 

元ネタ:管理人さんへひとこと

さらに元:文字列の全角半角判定

過去のエントリ:全角?半角?

お勉強:特番 Windows Vista の新文字セットが引き起こすトラブル(ITpro)

お勉強その2:小形克宏の「文字の海、ビットの舟」―― 文字コードが私たちに問いかけるもの(INTERNET Watch)


何というか、文字処理って、難しいですよ。

ごく最近、あるウェブサービスで住所を入力しました。「日本のどこか12丁目34番地」と。すると、「住所に半角文字が入力されています。全角文字だけを使用してください」と、エラーになりました。

なぜ?どうして?何のために?

郵便番号を ASCII 7bit の範囲で入力しろ、というのなら、まだわかります。なぜ住所から、ASCII 7bit の範囲を排除しなければならないのか。「わんくまハイツA棟」という住所は使ってはいけないの?それをおかしいと思いませんか?

「丈」という文字を名前に持っていらっしゃる方は多いと思いますが、「丈」の字は、本当は「��」(Vista なら表示される?右上に点がついている)、点がついていたりしませんか?「全角半角チェック」は、たいてい Shift_JIS にコード変換をして、1バイト文字か2バイト文字かで判別しますが、この字は Shift_JIS に割り当てがありません。すると、"?" に置き換わってしまいます。サロゲートペアなので、2つ。はい、「名前に半角文字が含まれています。全角文字だけを入力してください」って、怒られることになります。

もちろん、正規表現もこれに対応していません。「名前に「丈」の字がつく人」を検索しても、点付きの「丈」はヒットしません。全文検索するとき、異字体やサロゲートペア文字で書かれていると、ヒットできません。

文字列の全角半角判定(C# と VB.NET の質問掲示板)より:

□投稿者/ hei (2回)-(2007/08/08(Wed) 23:57:11)

私は銀行などに納品しているテキストファイルを生成しています。
納品形態は顧客ごとに違っていますが、
すべてShiftJISでフィールドによって全角・半角を分けています。
この経験から上の発言をしましたが、
全角半角を意識するように指示されることは珍しいですか?

私は、DOS 時代に UNIX と DOS の間でデータをやりとりしていたので、エンディアン問題や文字コードの問題には、Windows だけで仕事をしている人より慎重に向き合っていると思います。その上で、「なぜ Shift_JIS ?」と問いたい。全ての端末が Windows で、Shift_JIS のデータしか入力されないのであれば、それもひとつ。

ただし、この、狭い視野(あえてこの表現)で、「EUC_JP を使う UNIX は?メールは JIS-2022-JP だよ?EBCDIC なシステムを相手にするときはどうするの?」という件について、知らないで済ませるのは、どうかと思うのです。

私は独学で学んだためか、個人的な全角半角の定義は基本的に
「キーボードの全角・半角入力で入力されたもの」
程度の認識です。
みなさんがおっしゃっている「定義」の意味がいまひとつわからないのですが、
これ以降のレスで理解できたらと思います。

と、書きながら、その後には、

頻繁に出てくる文字で例を挙げます。
全角とは「0123456789」で、
半角とは「0123456789」です(あえて断言します)。

というのは、話が合わないのはどっちでしょう?

少なくとも、その直前に、

全角半角は、こういう表示上占める範囲を表す場合と、一文字が何バイトでできているかを表す場合があります。前者はプロポーショナルフォントの出現で意味を失い、後者はUTF-16では一定、UTF-8では3倍角や4倍角もありえる。

と、なぜ定義をしなければならないのか、出しています。今、あなたがご覧になっているこのページは、UTF-8 のコードが使われています。このコードでは、日本語の文字の多くは、3バイトです。"®" のような、Latain-1 で定義されている文字は、2バイトあります。欧文コードでは 0xae に定義されていて、1バイトなんですけどね。また、Vista ではメイリオ フォント、XP では MS UI ゴシック フォント、Mac では Osaka フォントで表示されていると思います。これらは、プロポーショナル フォントです。"l"(エル)と"m"(エム)で、表示に必要な幅が違います。ゆえに、何を持って「全角文字」「半角文字」というのでしょう?判別のための文字コードと、表示されるフォント、このふたつが一定の基準を満たさないと、「全角」や「半角」は問題にならないのです。

「私は Windows でしか仕事をしていないから、Shift_JIS が全てだ!」というのもいいでしょう。でも、本当に?Windows の内部コードは、とっくの昔に Unicode ですよ?開発環境も、少なくとも Visual Studio 6.0 の頃には、Unicode に対応しています。デフォルトは、Multi Byte Charactorset ですけど(ここ、文字集合と文字符号が一緒くたに扱われているという、突っ込み所)。API も、'A' と 'W' が用意されています。つまり、Unicode を扱うための準備は整っていて、そのための移行期間も十分に設けられています。大昔に書かれた、デバイス ドライバ寄りなプログラムのメンテナンスをしている私は、ほとんどの所を MBC で扱いながら、API 呼び出し直前に Unicode に変換しているコードに苛立っています。だれだ、こんな中途半端なコード書いたの!!

ユーザーが入力した「123-4567」と「123-4567」は違う郵便番号ですか?とあります。同じ郵便番号です。同じ郵便番号なのに、なぜ、これらの文字を対比するときに使う用語は、一般に「全角の数字・半角の数字」ではないですか?と分けてみたり、一般に「全角半角」という異なった文字を出力するのでこれらのチェック・変換は頻繁に行っています。のようなチェックが必要になったりするのでしょう?誰のための、何のためのチェックなの?同じなのだから、チェックする必要はないでしょう(郵便番号のフォーマットに一致しているかどうかのチェックは必要)。郵便番号の枠一杯に書いたときと、半分だけ使って書いたときで、別の文字になるのでしょうか?

しかし、実のところ、全角半角の区別をしなくていいのは、エンド ユーザだけです。プログラム製造に関わる人は、意識しなければなりません。なぜか。コンピュータが区別するからです。

人間は、文字を形で認識しています。このとき、「1」も「1」も、同じ字として認識します。しかし、コンピュータはそうではありません。コンピュータが認識するのは、それぞれの文字に割り当てられたコードです。コードが違うものは、別の字なのです。そのため、「1」と「1」は、別の字として認識されます。

.NET Framework の Regex クラスは、オプションによって同じに扱ってくれますが、それは .NET Framework の中だけの話です。そんな例外、この際無視します。

区別しないエンド ユーザが、区別するコンピュータに、直接データを渡してやることはできません。そこで、プログラムに携わる人は、区別をする/しないを切り替える緩衝材にならなくてはなりません。そのため、コンピュータが何を区別するのか、知る必要があります。

それなのに、考えなしに、「一般に、漢字モードで入力したものが全角、漢字モード OFF で入力したものが半角といわれている」から、そのまま受け入れてしまっていいのでしょうか?

私はこれまで学んできた中で、
全角半角のチェック・変換の質問には「VBのStrConv関数だよ」という
解説・回答はたくさん見てきましたが、
ここまで「厳密な定義」にこだわった意見にあったのは初めてです。
もちろんそれなりの意味があるのでしょうが、
結局理解できませんでした。

「今までは」、それでも良かったのですよ。Microsoft Charactorset CodePage 932 は、JIS だけでなく、NEC 拡張や IBM 拡張まで含んで定義されていたので、変換できない文字がなかったから。ところが、Oracle が Unicode を扱いだして、事情が変わりました。いわゆる、「Wave-Dash 問題」です。Oracle に "~" を登録して取り出すと、波の向きが反対になります。これは、Oracle 側が、CodePage 932 に合わせた文字セットを用意したことで、一応解決できています。9i 以降は、SJIS_TILDA だったかな?そんなコードに設定すれば、回避できるようになりました。

Unicode には、フォントを提供する人(になるのかな?)が自由に定義して良い領域があります。PC-9801 の頃の、「外字」に相当します。ここを使うと、当然文字化けが発生します。他の文字コードに変換できません。それを問題だと思わないのでしょうか。

こういった、これから発生してくるであろう問題が見えてくると、正規表現なんて使えて当たり前、そしてその限界に見捨てていて当たり前だと思っていますというのも、「当たり前」というのは言い過ぎとしても、納得できる意見のようだと思います。いかがでしょうか。

最初に出しているリンク先に、「日本の漢字には正字を元に、異字体、印刷標準字体がある」と書かれています。現在の所、これらには別々のコードが割り当てられ、同じものであるとは認識されません。今後、電子計算機による情報のデジタル化が進めば、同じ字であると認識されないことが問題になってくるでしょう(検索したときに検索できない、など)。そうすると、どれかの一文字に集約(「包摂」っていうんだって)される可能性もあります。このことを、日本の文化の衰退というのは、言い過ぎでしょうか?

投稿日時 : 2008年1月31日 22:36
コメント
タイトル
名前
Url
コメント