Help us understand the problem. What is going on with this article?

Webページにおける円記号「¥」(→バックスラッシュ)の文字化け問題の解決方法

(注意) この記事では、円記号をすべて、バックスラッシュをすべてと表記していますが、円記号は半角・全角のどちらの場合もあり、バックスラッシュはすべて半角のものとお考えください。

この記事は、
円記号(バックスラッシュ)に文字化けする現象はよく知られていますが、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の場合)
「えん」の変換候補のうち、右側に[環境依存]
と表示される候補の文字

のコード番号です。
MS-IMEにおけるA5コードの選択
Mac環境では、【5C】、【A5】とも、それぞれ別々に打ち込めるそうです。

全角記号の

全角記号のは、

(MS-IMEの場合)
「えん」の変換候補のうち、右側に[全]
と表示される候補の文字

です。
MSIME_全角.jpg
ユニコードとJISコードではコード番号が異なりますが、コード体系が異なるだけで、実質的には同じ文字を表示するらしいです。

Webページの文字参照

「¥」 「¥」 「¥」
これらは、Webページにおいて、「文字参照」と呼ばれる仕組みでが表示されるようです。3種類ありますが、実質的にはどれも同じような気がします。(どう違うのか、私にはわかりません。)

ちなみに、「\」はフォントによって、が表示されたりが表示されたりするようです。

1.2. フォントが原因の文字化け

「フォント」とは、各種の文字コードをどのように表示するか(どのようなドットで表現するか)をまとめたファイルです。フォントには、たくさんの種類が存在し、どのフォントが利用できるか、そのうちのどれを優先的に使用するかはケースバイケースです。Webページの場合は、CSSで指定したり、ブラウザがそれを上書きする場合があります。

フォントによっては、収録していない文字コードが存在し、【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保存時のエラー画像
などとエラー表示が出て、うまく保存することができません。
このエラーの原因がわからないまま、強引に保存を強行してしまうと、
【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ページで円記号が文字化けする原因

  1. で見てきた通り、円記号が文字化けする原因には、
* 文字コード
* フォント
* エンコード(エンコーディング)

の3種類がありました。
Webページでは、これらのいずれもが原因となりうるため、問題をややこしくしています。
そこで、解決のヒントを探すため、
どのフォントで、どのエンコードで、どの文字コードがどう表示されるか
調べてみることにしました。

2.1. 結果

以下の表中、
「全角」とあるのは全角がどう表示されたか、
「5C」とあるのは、【5C】コードがどう表示されたか、
「A5」とあるのは、【A5】コードがどう表示されたか、
「&○○○;」とあるのは、文字参照(&○○○;)がどう表示されたか、
を表します。
UTF-8の調査結果

Shift_JISエンコードでは、【A5】コードをファイルに保存できなかったので、代わりに文字参照(&#xA5;)の表示を調査しました。
Shift_JISの調査結果

EUC-JPエンコードでも、【A5】コードをファイルに保存できなかったので、代わりに文字参照(&#xA5;)の表示を調査しました。
EUC-JPの調査結果

これらの結果を見ると、「文字参照(&yen;)」の表示は安定して必ず「円記号」となっています。

ということは、Webページ上で記号を必ず表示させたい場合は、
「文字参照(&yen;)」を使えばいいのでは
、という仮説に至ったというわけです。

しかし、残念ながら、これが本当に正しいかどうかは確定しません。
すべてのフォントで必ず記号が表示されるかどうかを確認するのは、事実上不可能です。

もし、このページを見ている皆さんの中で、「一般的な環境で表示されなかった」という事実があれば、どんな環境かお教えいただきたいと思います。

一方、「文字参照(&#x5C;)」の表示は【5C】コードと変わらない結果でした。これにより、今のところ、Webページ上で「(半角)バックスラッシュ」を必ず表示させる方法は、その文字に欧文フォントを指定するなど、とても面倒な方法しかないということになります。日本語フォントだからとはいっても、「文字参照(&#x5C;)」の表示が記号というのはなんだかなーという感じです。

とはいえ、Webページ上で「(半角)バックスラッシュ」を必ず表示させなければならないことはあまり無いかな.....

Qiibow
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away