Java : エスケープシーケンスの基本

エスケープシーケンスを使うと、文字列リテラルとして、改行やタブなどの非グラフィックス文字を表記できます。
代表的なエスケープシーケンスには、

  • \n … 改行(LF)
  • \r … 行頭復帰(CR)
  • \t … タブ

などがあります。

本記事では、そんなエスケープシーケンスの基本をご紹介します。

注意:

  • エスケープシーケンスには、バックラッシュ ( ) が使われます。
    ただし、環境によっては円記号 ( ¥ ) で表示されることもあります。
  • 本記事でも と ¥ が混在して表示されるかもしれません。
    その場合は、どちらも同じものとしてご理解ください。

概要

3.10.7. Escape Sequences
In character literals, string literals, and text blocks (§3.10.4, §3.10.5, §3.10.6), the escape sequences allow for the representation of some nongraphic characters without using Unicode escapes (§3.3), as well as the single quote, double quote, and backslash characters.

エスケープシーケンスを使うと、

  • 文字リテラル
  • 文字列リテラル
  • テキストブロック

で、改行やタブなどの非グラフィック文字を表記できるようになります。

リテラルとは、ソースコード上で文字や文字列の値を直接表記したものをいいます。

// 文字列リテラルの例
final String str = "abcde";

例えば文字列のリテラルは、

 "abcde"

というように、文字列をダブルクォート文字 ( " ) で囲むことで表記します。

次に、文字列リテラルで改行を表記する例を見てみましょう。

final String str = "abc\n123\nあいうえお";

System.out.println(str);

結果は次のように表示されます。

abc
123
あいうえお

改行のエスケープシーケンスは \n です。

文字列リテラルとしては

 "abc\n123\nあいうえお"

という1行で表記されます。
しかし、それを実際に表示すると \n は改行になります。

このように、改行のような非グラフィック文字をリテラルとして表記するための仕組みが エスケープシーケンス です。

補足

なぜエスケープシーケンスが必要なのか

もしエスケープシーケンスを知らないかたが、文字列リテラルに改行を入れたいと考えたとき、

final String str = 
"abc
123
あいうえ";

と表記したくなるかもしれません。
しかし、これはコンパイルエラーとなります。

Javaの構文的に許容されていないためですね。

他には、ダブルクォート文字 ( " ) そのものを文字列リテラルで表記したい場合も、エスケープシーケンスがないと困ることになります。

final String str = "aaa"bbb";

aaa と bbb の間にダブルクォート文字 ( " ) を入れたいのですが、これもコンパイルエラーとなります。
ダブルクォート文字が3つあるので、どれが文字列リテラルの開始と終了の " なのか、Javaコンパイラが判断できないためです。

文字列リテラル1

そこでエスケープシーケンスが必要になります。
ダブルクォート文字自体のエスケープシーケンスは、\" です。

final String str = "aaa\"bbb";

System.out.println(str);

// 結果
// ↓
//aaa"bbb

エスケープシーケンスを使い、文字列リテラリでダブルクォート文字が表記できました。

aaa と bbb の間のダブルクォート文字( " )は、バックスラッシュ( \ ) があるのでエスケープシーケンスです。
Javaコンパイラは \" をいったん除外して、aaaの前の " と bbb の後の " をリテラル文字列の開始と終了であると判断できます。

文字列リテラル2

まとめると…

文字や文字列リテラルの表記では、表現できる文字に構文上の限界があります。
その限界を回避するための手段が エスケープシーケンス というわけですね。

基本的なエスケープシーケンス一覧

基本的なエスケープシーケンスの一覧になります。

エスケープシーケンス 簡単な説明 ユニコード表記
\b バックスペース \u0008
\s スペース \u0020
\t タブ \u0009
\n 改行(LF) \u000a
\f 改ページ(FF) \u000c
\r 行頭復帰(CR) \u000d
\" ダブルクォート文字 \u0022
\' シングルクォート文字 \u0027
\\ バックスラッシュ文字 \u005c

エスケープシーケンスの基本構文は

  • \ + 特定の文字

となります。

ユニコードエスケープ

3.3. Unicode Escapes

ユニコードエスケープは、ユニコード値で直接文字を指定するエスケープシーケンスです。

  • \u + 16進数表記の4桁の数字(ユニコード値)

で表記します。

ユニコード値は、例えば 'a' という文字には 0x0061、'あ' という文字には 0x3042 が割り当てられています。

以下、ユニコードエスケープを使ったコード例となります。

final String str = "\u0061\u0062\u0063";

System.out.println(str);

// 結果
// ↓
//abc
final String str = "\u3042\u3044\u3046";

System.out.println(str);

// 結果
// ↓
//あいう

補足

  • ユニコードとは、世界中の文字の1つ1つに通し番号(コード)を割り当てたものです。
    詳細は「Unicode - Wikipedia」などをご参照ください。
  • エスケープシーケンスの1つに、OctalEscapeがあります。
    ただし、Java SE 言語仕様にて、代わりにユニコードエスケープを使うことが推奨されているため、本記事では割愛しています。

改行の抑止

改行の抑止は、テキストブロックでのみ使えるエスケープシーケンスです。
まずは、改行をエスケープしない例を見てみましょう。

final String textBlock = """
        aaa
        123
        あいうえお
        """;

System.out.println(textBlock);

// 結果
// ↓
//aaa
//123
//あいうえお

テキストブロックでは、ソースコード上で改行すれば、それは文字列の改行 ( \n ) となります。

次に改行をエスケープする例になります。

final String textBlock = """
        aaa\
        123\
        あいうえお\
        """;

System.out.println(textBlock);

// 結果
// ↓
//aaa123あいうえお

テキストブロックの各行の最後をバックスラッシュ( \ ) にすることで、テキストブロックによる改行を抑止できます。

例えば、非常に長い1行のテキストを、

  • ソースコード上では改行して見やすく
  • でも、実際の文字列には改行は含めない

という場面で使えそうですね。

テキストブロックのすすめ

リテラル表記中にエスケープシーケンスが多いと、けっこうコードが見づらくなります。

final var str = "<root>\n" +
        "  <child attr=\"abc\"/>\n" +
        "</root>\n";

System.out.println(str);

// 結果
// ↓
//<root>
//  <child attr="abc"/>
//</root>

上記は、シンプルなXML文字列の例ですが、意外と見づらくはないでしょうか。

そんなときは、テキストブロックを使うことをおすすめします。
Java 15 から追加された仕様で、改行やダブルクォート文字をエスケープなしで表記できます。

final var textBlock = """
        <root>
          <child attr="abc"/>
        </root>
        """;

System.out.println(textBlock);

// 結果
// ↓
//<root>
//  <child attr="abc"/>
//</root>

テキストブロックを使った例になります。
だいぶ見やすくなったのではないでしょうか。

テキストブロックについてもう少し詳しく知りたいかたは、「テキストブロックの基本」も参照いただければ幸いです。


関連記事

ページの先頭へ