(注意) この記事では、円記号をすべて¥
、バックスラッシュをすべて\
と表記していますが、円記号は半角・全角のどちらの場合もあり、バックスラッシュはすべて半角のものとお考えください。
この記事は、
円記号¥
が\
(バックスラッシュ)に文字化けする現象はよく知られていますが、Webページに関しては、「文字参照」を利用することで解決するのでは? という仮説に至るまでの話です。(仮説ではありますが、今のところうまくいくのでは?という印象です。)
他のブラウザ・OSでも検証したいのですが、下記の環境だけでもかなり複雑になってしまったので、もし、一般的な環境で、違う結果が出る場合があったら教えてください。
検証環境
Windows 10 Home (Ver.1909) Firefox 79.0 (64 ビット)
1. 円記号¥
が文字化けする原因
下記のようなものが挙げられます。
* 文字コード
* フォント
* エンコード(エンコーディング)
1.1. 文字コードが原因の文字化け
円記号¥
を表す文字コードには、下記のようなものが挙げられます。
* 5C...半角記号の¥(一部の環境では「\」(バックスラッシュ)が表示)
* A5...半角記号の¥(Windowsでは「・」(半角中点)が表示されることも)
* U+FFE5(ユニコード)、216F(JISコード)...全角記号の¥
* Webページの文字参照(「¥」、「¥」、「¥」)
5C
【5C】は、Windowsでは¥
キー(または\
キー)で打ち込まれる文字のコード番号です。
A5
【A5】は、Windowsでは
(MS-IMEの場合)
「えん」の変換候補のうち、右側に[環境依存]
と表示される候補の文字
のコード番号です。
Mac環境では、【5C】\
、【A5】¥
とも、それぞれ別々に打ち込めるそうです。
全角記号の¥
全角記号の¥
は、
(MS-IMEの場合)
「えん」の変換候補のうち、右側に[全]
と表示される候補の文字
です。
ユニコードとJISコードではコード番号が異なりますが、コード体系が異なるだけで、実質的には同じ文字を表示するらしいです。
Webページの文字参照
「¥」 「¥」 「¥」
これらは、Webページにおいて、「文字参照」と呼ばれる仕組みで¥
が表示されるようです。3種類ありますが、実質的にはどれも同じような気がします。(どう違うのか、私にはわかりません。)
ちなみに、「\」はフォントによって、¥
が表示されたり\
が表示されたりするようです。
1.2. フォントが原因の文字化け
「フォント」とは、各種の文字コードをどのように表示するか(どのようなドットで表現するか)をまとめたファイルです。フォントには、たくさんの種類が存在し、どのフォントが利用できるか、そのうちのどれを優先的に使用するかはケースバイケースです。Webページの場合は、CSSで指定したり、ブラウザがそれを上書きする場合があります。
Webページを見たユーザーが、どのフォントを利用することができるかは、ユーザーの環境によって異なります。現在は、Windows、Mac OS、Android、iPhone(iOS)、iPad(iPadOS) のそれぞれの環境(標準状態でインストールされているフォント)を想定したWebページ作りが必要でしょう。
フォントによっては、収録していない文字コードが存在し、【5C】コードを¥
と表示するか、それとも\
(バックスラッシュ)と表示するか、【A5】コードを収録するか、それとも収録しないか、などは、フォントの製作者に任されています。
また、ほとんどの「欧文フォント」では、日本語を扱いません。そのため、「全角記号」の¥
は日本語特有の文字なので、収録されていない場合が多いです。
しかし、Webページの場合は、ブラウザが気を利かせて、表示できないはずの文字を、ブラウザの既定フォントで代替表示する場合があります。
1.3. エンコードが原因の文字化け
「エンコード」(エンコーディング)とは、
各種の文字コード体系を、さらにコード化するものです。なぜそのようなことをするのかというと、文字と文字の区切りをはっきりさせるためです。
例えば、ユニコードの文字コード体系でいうと、
半角数字の「0」という文字は【30】というコード、
半角英大文字の「B」という文字は、【42】というコード
で表されます。そして、
日本語の「あ」という平仮名は、【3042】というコード
になります。
【30】 ...半角数字の「0」
【42】 ...半角英大文字の「B」
【3042】...平仮名の「あ」
そうすると、【3042】という文字コードがあった場合、どこが文字の区切りか、コンピュータが判断できないため、それが「0B」なのか、それとも「あ」なのか、区別できません。そういうのをはっきりさせるための「決まり」が、「エンコード」(エンコーディング)というわけです。以下、単に「エンコード」と表記します。
エンコードの方式には、ユニコード・JISコードともに、何種類もあります。
日本語Webページの場合は、
+ UTF-8 (ユニコード体系)
+ Shift_JIS (JISコード体系)
+ EUC-JP (JISコード体系)
のほぼ3種類だけですが、
Windows の「メモ帳」アプリの場合は、
+ UTF-8 (既定)
+ ANSI (Shift_JIS とほとんど同じ。Windows 10 (Ver.1808) までの既定)
その他のエンコードで保存することができます。
Webページで、エンコードが原因の文字化けを防ぐには、
* レスポンスヘッダーの指定エンコード
* HTMLファイル(Webページの本体)の作成・保存エンコード
* HTMLファイルのmeta要素の指定エンコード
これら3つが一致していることが極めて重要です。
特に上から2つが重要です。
1.3.1. レスポンスヘッダーのエンコード指定
Webサーバーは、レスポンスヘッダーを送信して、ブラウザからリクエストがあったページのエンコードを、伝えてくれます。ブラウザは、その指定されたエンコードで、Webページを解釈して画面に表示します。
ところが、Webサイト製作者が、うっかりその指定を忘れるか、あるいはデフォルト(既定)のエンコード(または指定したエンコード)と異なるエンコードでWebページを製作してしまうと、誤った(デフォルトの)レスポンスヘッダーを信じたブラウザが、文字化けを起こしてしまいます。
解決策は、正しいレスポンスヘッダーを送信するです。
下記に、PHPを利用したヘッダー送信の一例を挙げておきます。
header("Content-type: text/html; charset=EUC-JP");
レスポンスヘッダーは、Webページのmeta要素の指定より優先です。
なお、レスポンスヘッダーは、レスポンスbodyが送信される前に送信しなければなりません。ほんの一文字でもレスポンスbodyが送信された後では無効です。
ファイルの先頭に見えないBOMが存在していて、それがレスポンスbodyとして送信されてしまい、直後にレスポンスヘッダーを送信しようとしてもダメ.....という例があったそうです。
1.3.2. HTMLファイル(Webページの本体)の作成・保存エンコード
さて、Webサーバーが送信したレスポンスヘッダーに続いて、Webサーバーは「レスポンスbody」を送信します。これがWebページの本体です。
このWebページは、ページ製作者がWebサーバーの適切なディレクトリに保存(通常は、ページ製作者のローカルコンピュータで製作してから、サーバーへアップロード)するのですが、このページを作成・保存するときに、レスポンスヘッダーで指定したエンコードとは異なるエンコードで作成・保存してしまうと、この文字化けが起こります。
解決策は、レスポンスヘッダーと同じエンコードでWebページを作成・保存するです。
Webページや、その元となるファイルを作成・保存するときには、必ず、エンコードを確認してから保存することが重要です。
エンコードによっては、保存できない文字がある
Windows では、【A5】コードの文字をうまく保存できない場合があります。
「メモ帳」アプリの場合、【A5】コードの文字を表示するには、
(MS-IMEの場合)
「えん」の変換候補のうち、右側に[環境依存]
と表示される候補の文字を選択
します。
すると、画面に¥
が表示されたりしますが、この文字が含まれる文書をJISコード体系のエンコード(ANSI)で保存しようとすると、
このファイルはANSIテキストファイルとして保存すると失われてしまうUnicode形式の文字を含んでいます。.....
などとエラー表示が出て、うまく保存することができません。
このエラーの原因がわからないまま、強引に保存を強行してしまうと、
【A5】コードの文字のはずが、【5C】コードに変換されてしまいます。
この時点で、すでに文字化けが発生したと言うことができます。
このように、Windows では、【A5】コードの文字を正しく保存できないことがあります。そのため、Windows で そのような Webページを作成するときには、「UTF-8」エンコードで保存する必要がありそうです。
また、「サクラエディタ(Ver.2.4.1)」というテキストエディタで、【A5】コードを「EUC-JP」エンコードで保存しようとしたときも同様のエラー表示が出ました。強引に保存を試みたところ、【3F】コード(?クエスチョンマーク)に変換されてしまいました。しかし、「UTF-8」エンコードでなら、【A5】コードを保存することはできました。
なお、Windows 10 付属の「メモ帳」アプリでは、「EUC-JP」エンコードでファイルを作成・保存することができないようです。Webページを製作する場合には、目指すエンコードが使えるテキストエディタを使用するようにしましょう。
Webページの製作者がエンコードを勘違い
当然のことながら、レスポンスbodyとして送信されるWebページの本体は、レスポンスヘッダーで指定するエンコードと一致していなければ文字化けします。レスポンスヘッダーでは"EUC-JP"が指定されることになっているのに、WebページとなるHTMLファイルをうっかり"UTF-8"で作成・保存すると文字化けしてしまいます。
こういうのは、連絡ミスによっても起こり得ます。サイト管理者が「EUC-JPでサイトを作る」と決めているのに、ページ製作者が違うエンコードでページを作ってしまった場合などです。
Webページ全体が文字化けしている場合は、ほぼ全て、このエンコードの指定ミスが原因でしょう。
1.3.3. HTMLファイルのmeta要素のエンコード指定
一例を挙げると、
<mata charset="UTF-8">
のようなものです。(HTML5の場合)
レスポンスヘッダーでエンコードが指定されない場合に、ここでの指定がWebページのエンコードとして認識されるようです。
2. Webページで円記号¥
が文字化けする原因
-
で見てきた通り、円記号
¥
が文字化けする原因には、- 文字コード
- フォント
- エンコード(エンコーディング)
の3種類がありました。
Webページでは、これらのいずれもが原因となりうるため、問題をややこしくしています。
そこで、解決のヒントを探すため、
どのフォントで、どのエンコードで、どの文字コードがどう表示されるか
調べてみることにしました。
2.1. 結果
以下の表中、
「全角」とあるのは全角¥
がどう表示されたか、
「5C」とあるのは、【5C】コードがどう表示されたか、
「A5」とあるのは、【A5】コードがどう表示されたか、
「&○○○;」とあるのは、文字参照(&○○○;)がどう表示されたか、
を表します。
Shift_JISエンコードでは、【A5】コードをファイルに保存できなかったので、代わりに文字参照(¥)の表示を調査しました。
EUC-JPエンコードでも、【A5】コードをファイルに保存できなかったので、代わりに文字参照(¥)の表示を調査しました。
これらの結果を見ると、「文字参照(¥)」の表示は安定して必ず「円記号」となっています。
ということは、Webページ上で¥
記号を必ず表示させたい場合は、
「文字参照(¥)」を使えばいいのでは、という仮説に至ったというわけです。
しかし、残念ながら、これが本当に正しいかどうかは確定しません。
すべてのフォントで必ず¥
記号が表示されるかどうかを確認するのは、事実上不可能です。
もし、このページを見ている皆さんの中で、「一般的な環境で表示されなかった」という事実があれば、どんな環境かお教えいただきたいと思います。
一方、「文字参照(\)」の表示は【5C】コードと変わらない結果でした。これにより、今のところ、Webページ上で「(半角)バックスラッシュ」を必ず表示させる方法は、その文字に欧文フォントを指定するなど、とても面倒な方法しかないということになります。日本語フォントだからとはいっても、「文字参照(\)」の表示が¥
記号というのはなんだかなーという感じです。
とはいえ、Webページ上で「(半角)バックスラッシュ」を必ず表示させなければならないことはあまり無いかな.....