torutkのブログ

ソフトウェア・エンジニアのブログ

macOS上でのバックスラッシュと円マークの違いにハマる

macOS上で文字は、バックスラッシュと円マークが区別される

macOS文字コードUnicodeUTF-8)で扱います。プログラミングしているソースコードUTF-8で扱われます。このUTF-8では、バックスラッシュ「\」と円マーク「¥」はそれぞれ別な文字として扱われ、文字コードも異なります。バックスラッシュは0x5cの1バイトで表現され、円マークは0xc2 0xa5の2バイトで表現されます。

JIS配列のMacBookのキーボードで右上端の方にある[¥]キーを打鍵すると、円マーク「¥」がエディタに入力・表示されます。

Windows日本語環境でソースファイルの文字コードUTF-8としたとして

Windows環境でも、Javaプログラミングの際はソースファイルの文字コードUTF-8にすることが多いです。しかし、Windows環境で使用するフォントによってバックスラッシュ文字(UTF-8で0x5c)は、バックスラッシュとして表示されたり、円マークとして表示されたりします。英語フォントでは前者、日本語フォントでは後者が多いです。ただし、日本語フォントでもプログラミングむけとされるフォントなどでは前者となるものもあります。

そのため、Windows日本語環境を長年使っていると、半角のバックスラッシュも半角の円マークも同じ文字という認識になります。

macOS上で正規表現を使うプログラミングをしていたら

macOS上でJavaプログラミングをしていたら、正規表現の処理がなぜかうまくいかない状況に陥ってしまいました。 次は、macOS上でEclipseJavaソースコードを記述した時のものです。(キーボードから打ち込んだ)

f:id:torutk:20211225211135p:plain
macOSEclipse上で正規表現を使う記述をした(円マーク使用)

ところが実行すると、正規表現にマッチしません。おかしい。 そこで、ターミナルでコマンドラインからjshellを起動し、対話モードで正規表現を試してみました。

f:id:torutk:20211225212915p:plain
macOSのターミナル上でjshellを起動し対話モードで正規表現を使う

ターミナル上の対話モードでは正規表現にマッチします。なぜ、と悩みました。

そこで、何か見落としている違いがあるのではとターミナル上の正規表現Eclipse上にコピーペーストして比較してみました。

f:id:torutk:20211225213350p:plain
Eclipse上でキー入力した正規表現文字列とターミナル上からコピーペーストした正規表現文字列

特に間違っている箇所はなさそうです1

そこで、何か見えないところに違いがあるのではないかと、ソースファイルをヘキサダンプしてみました。

f:id:torutk:20211225215634p:plain
キー入力した正規表現とターミナルからコピペした正規表現をファイルのヘキサダンプで比較

^¥¥|の部分と^\\|の部分を図で赤枠で囲っていますが、バイナリで見ると文字コードが違うことがわかります。円マーク「¥」は、0xc2 0xa5 となっており、バックスラッシュ「\」は、0x5cとなっています。

そこで、ソースコード正規表現をバックスラッシュに書き直したら、問題なく動作するようになりました。 JIS配列のMacBookでは、option + ¥ キーでバックスラッシュが入力されます。

f:id:torutk:20211225220257p:plain
macOS上のEclipseで円マークをバックスラッシュに書き換えた

UTF-8環境では、半角の円マークと半角のバックスラッシュが違う

一般的な呼び方 記号 Unicode Unicode UTF-8 Shift JIS
バックスラッシュ \ Reverse Solidus U+005C 0x5C 該当なし
円マーク ¥ Yen Sign U+00A5 0xC2 0xA5 0x5C

Windows日本語環境では、US ASCIIの文字コードを流用しつつ0x5Cの文字をバックスラッシュから円マークに置き換えた文字集合が使われています。そのため、バックスラッシュと円マークが同じ文字コードと認識しがちです。

一方、UTF-8ではバックスラッシュと円マークが区別されています。

IntelliJ IDEAであれば

f:id:torutk:20211225224736p:plain
IntelliJ IDEAで正規表現記述と円マーク、バックスラッシュのハイライト表示

macOS上でIntelliJ IDEAを使ってソースコードを表示すると、文字列中での正規表現のハイライト(色付け)がバックスラッシュと円マークで異なっているのが分かります。


  1. この時点で、同じエディタ上に円マーク「¥」とバックスラッシュ「\」が同居していることに気づけばよかったのですが。