Paraphrase における文字列データの記述方法について

飯倉宏治

Paraphrase では多くのプログラミング言語と同様に、文字列を値として使用可能です。 文字列データの記述は、これまた多くのプログラミング言語と同様に ダブルクォート(")またはシングルクォート(')で括ります。

     "文字列"
     '文字列'

文字列データの開始を示すクォートは同じ種類でなければなりません。 ダブルクォートで文字列データの記述を開始した場合は、 その文字列データはダブルクォートにて終了します。

このような規則があるため、ダブルクォートを用いると、 次のようにシングルクォートを含んだ文字列データの記述が可能となります。

     "ASCII コード 0x41 は文字列 'A' を示します。"

ダブルクォートにて括られた文字列では、 シングルクォートに特別な機能(意味)は存在しません。 なので、文字列中に必ずしも偶数個存在する必要はありません (奇数個でも何ら問題は生じません)。

逆に、シングルクォートで括られる場合では、 文字列中のダブルクォートは単なる文字として取り扱われます。

     'ASCII コード 0x41 は文字列 "A" を示します。'

先程の例と同様、この例では文字列中のダブルクォートの個数は偶数でも奇数でも構いません。

次のセクションで説明しますが、 ダブルクォートで括った場合とシングルクォートで括った場合では、 特殊文字の表現能力が異なります。 改行文字などの特殊文字が文字列データ中に存在しない場合は、 シングルクォートで括ると良いでしょう。

ダブルクォートとシングルクォートの使い分け

ダブルクォートとシングルクォートの使い分けですが、 特殊文字を示すエスケープシーケンスの取り扱いが異なります。 ダブルクォートで括られる文字列データを括った場合、 バックスラッシュをエスケープ文字として用いる以下の特殊文字が使用可能です:

ダブルクォートで括られた文字列中で使用可能な特殊文字
\n 改行
\r 復帰
\t タブ
\" ダブルクォート
\' シングルクォート
\\ バックスラッシュ

一方、シングルクォートにて括られる文字列中では、 上記の殆どの特殊文字は使用できません。 それは、シングルクォートは括られた 文字列そのものを表す生文字列(raw 文字列)のために用いられるからです。

シングルクォートによる生文字列(raw 文字列)

ダブルクォートで括られた文字列中では、 バックスラッシュが各種の特殊文字のためのエスケープ文字として使用されます。 しかし、この機能により文字列データの記述が煩雑になる場合があります。 例えば、正規表現のパターンを記述する場合などです。

正規表現では数値を示すために\dと表記します。 ある文字列から数字を 3 つ取り出すための正規表現は \d\d\dとなります。 ダブルクォートを使った場合、バックスラッシュ自体を表すため、 バックスラッシュによるエスケープが必要となっています。 一方、シングルクォートを用いる場合は、 原則としてバックスラッシュはエスケープ文字ではなく、 単なる文字として解釈されます。 なので、ダブルクォートとシングルクォートを用いて、 正規表現 \d\d\d を表すと次のようになります:

     '\d\d\d'
     "\\d\\d\\d"

今回は簡単な例ですので、3 文字しか違いはありませんが、 複雑な正規表現の場合、この差は大きくなります。

正規表現等におけるバックスラッシュの増大を避けるため、 いくつかのプログラミング言語では、 記述された文字列データをそのままの文字列として取り扱う 生文字列(raw 文字列)という機能が提供されています。 Paraphrase ではシングルクォートで括られる文字列が、 この生文字列となります。

以下は Make A Lisp におけるトークン切り出し部分で使われている正規表現の例です。 シングルクォートで括る場合は、

'[\s,]*(~@|[\[\]{}()\'`~^@]|"(?:\\.|[^\\"])*"?|;.*|[^\s\[\]{}(\'"`,;)]*)'

となりますが、これをダブルクォートで括ると

"[\\s,]*(~@|[\\[\\]{}()'`~^@]|\"(?:\\\\.|[^\\\\\"])*\"?|;.*|[^\\s\\[\\]{}('\"`,;)]*)"

となり、バックスラッシュが増大しています。 一方、シングルクォートを用いた raw 文字列の場合、 元の正規表現の表記と異なる部分はシングルクォートを表すための エスケープ文字の追加だけとなり、 よりオリジナルの正規表現に近い表記となっています。

このように、シングルクォートで括られた文字列中では、 バックスラッシュは基本的にはエスケープ文字としての機能を有しません。 そのため、バックスラッシュを多用する正規表現などでも、 バックスラッシュ文字の増大をある程度抑制することが可能となります。

以下に、シングルクォートで括られた文字列データ中にて、 バックスラッシュがエスケープ文字として機能するものを示します:

シングルクォートで括られた文字列中で使用可能な特殊文字

\' シングルクォート
\0 空文字

多くの場合、特に意識することなくそのまま表現できるかと思いますが、 文字列データの最後の文字がバックスラッシュの場合は少し注意が必要となります。 それは、'〜\'という文字列では、最終文字列のバックスラッシュが その直後のシングルクォートのためのエスケープ文字として 解釈されてしまうからです。

このような場合には、ダミーの空文字\0を文字列の最後に置いて下さい。 例えば、〜\という文字列データを生成する場合には

     '〜\\0'

として下さい。

備考:空文字について

空文字は何もデータを生成しませんので、 'abc''\0a\0b\0c\0\0' は 同じ文字列データ abc を生成します。 また、空の文字列 '''\0' などとも記述できます (が、使い道はあまり無いかと思います)。