区切り文字

は、コンピュータ言語やデータ通信において独立した領域の境界を特定するために入れられる文字であるFederal Standard 1037C - Telecommunications: Glossary of Telecommunication Terms。例えば、コンマ区切りの文字列において、コンマ (,) は各フィールドの境界を表す「フィールド区切り文字」の役割をしている。

区切り文字は、データストリームで境界を指定する方法の1つである。別の方法として、各フィールドの先頭にフィールド長を記述する方法もある describing the method in Hollerith notation under the Fortran programming language.。

 概要 
区切り文字は以下の2種類に分けられる。

 フィールド区切り文字・レコード区切り文字（例: コンマや改行）
 範囲指定区切り文字（例: 括弧やダブルクォート）

フィールド区切り文字・レコード区切り文字
フィールド区切り文字はデータフィールドを分離し、レコード区切り文字はフィールドのグループを分離する p. 141。

例えば、CSVファイルはコンマをフィールド間の区切り文字として、改行コードをレコード間の区切り文字として使用している。

以下は、CSVファイルのフォーマットを使用した簡単なフラットファイルデータベースのテーブルの例である。
fname,lname,age,salary
nancy,davolio,33,$30000
erin,borakova,28,$25250
tony,raphael,35,$28700

範囲指定区切り文字
範囲指定区切り文字は、テキストの範囲の最初と最後を示すものである p. 319。

よく使われる範囲指定区切り文字には、以下のものがある。
 区切り文字 説明 ( ... ) 丸括弧。LISPの構文は、主に丸括弧を使用することで判別可能であるp. 3。 { ... } 波括弧 references C-style programming languages prominently featuring curly brackets and semicolons. [ ... ] 角括弧 < ... > 山括弧Describes syntax and delimiters used in HTML. " ... " ダブルクォート。を表すのに使われるDescribes string literals.。 ' ... ' シングルクォート。文字リテラルを表すのに使われる。 <? ... ?> XMLのを表すのに使われる Describes XML processing instruction. p. 21.。 /* ... */ いくつかのプログラミング言語でコメントを表すのに使われる Describes single-line and multi-line comments. p. 72.。 <% ... %> いくつかのWebテンプレートで言語の境界を特定するのに使用する。これは「テンプレート区切り文字」とも呼ばれる See e.g., Smarty template system documentation, "escaping template delimiters".。

慣習
慣習的に、プラットフォームによって特定の区切り文字が使われるInternational Organization for Standardization (December 1, 1975). "[ The set of control characters for ISO 646]". Internet Assigned Numbers Authority Registry. Alternate U.S. version: . Accessed August 7, 2005.。以下に、そのいくつかの例を示す。

プログラミング言語
（も参照）
    文字列リテラル  文の区切りまたは文末 Pascal シングルクォート  セミコロン C言語 ダブルクォート、シングルクォート  セミコロン

フィールド区切り文字・レコード区切り文字（ASCII、制御文字も参照）

    フィールドの終了  レコードの終了  ファイルの終了 Unix, OS X, Amiga OS タブ  LF  （なし） Windows, MS-DOS, OS/2, CP/M タブ  CRLF  Control-Z Describes use of control-z. p. 156, Classic Mac OS, AppleDOS, ProDOS, GS/OS タブ  CR  （なし） ASCII/Unicode UNIT SEPARATORPosition 31 (U+001F)  RECORD SEPARATORPosition 30 (U+001E)  FILE SEPARATORPosition 28 (U+001C)

区切り文字衝突
区切り文字衝突（）とは、テキスト中のある文字が区切り文字として解析され、意図しない動作を引き起こす問題である describing solutions for embedded-delimiter problems p. 472.。例えばCSVファイルの場合、フィールドにコンマを含む値（例: 38,915円87銭）を入れようとするとフィールド区切り文字衝突が起こり、複数行の値を入れようとするとレコード区切り文字衝突が起こる。XMLの場合、フィールドに山括弧を含む値を入れようとすると区切り文字（フィールド区切り文字・レコード区切り文字のどちらも）衝突が起こる。テキストファイルではフィールド区切り文字・レコード区切り文字の衝突はよく発生する。

悪意のあるユーザーや攻撃者は、この問題を故意に利用しようとするかもしれない。従って、区切り文字衝突は、セキュリティホールやエクスプロイトの原因となり得る。悪意のあるユーザーはSQLやHTMLのような言語で、区切り文字衝突を利用してSQLインジェクションやクロスサイトスクリプティングのような攻撃を行う。

解決法
区切り文字衝突は非常に一般的な問題なので、それを回避する様々な方法が考案されている。

データストリームに現れそうにない文字（または文字列）を区切り文字として選ぶことによって、問題を回避する方法がある。この方法は多くの場合は通用するが、その文字がデータストリームに現れる確率はゼロではなく、また、悪意のある攻撃に対して安全ではない。よって、この方法は通常はとられない。

ASCII制御文字
ASCIIとUnicodeの文字セットではこの問題を回避するために、区切り文字として使用するための非表示の制御文字を用意している。それらの文字はASCIIで28 (0x1C) から31 (0x1F) に割り当てられている。

 ASCII #  Unicodeでの文字名  一般名  使用法 28  INFORMATION SEPARATOR FOUR  ファイル分離文字 (FS:file separator)  ファイルの終端、または、別のファイルとの間。 29  INFORMATION SEPARATOR THREE  グループ分離文字 (GS:group separator)  データのグループの間。単純な構造のデータファイルでは必要ない。 30  INFORMATION SEPARATOR TWO  レコード分離文字 (RS:record separator)   レコードまたは行の終端。 31  INFORMATION SEPARATOR ONE  ユニット分離文字 (US:unit separator)  レコードの中のフィールドとフィールドの間。行の中のメンバとメンバの間。

ASCII 31のユニット分離文字をフィールド区切り文字として、ASCII 30のレコード分離文字をレコード区切り文字として使用することで、フィールド区切り文字・レコード区切り文字の問題は解決するDiscussion on ASCII Delimited Text vs CSV and Tab Delimited。

エスケープ文字
区切り文字衝突の他の解決法として、エスケープ文字を使用する方法がある。これは、区切り文字の前にエスケープ文字を置くことで、その文字は区切り文字として使用する意図ではないことを明示するものである。言語設計の見地からはこれで十分であるが、以下のような欠点もある。

 大量のエスケープ文字が入ることで可読性が低くなる。例えば、Perlの正規表現の中で「/」という文字自体を使用したいときは「\/」のように書くが、「//」のように2つ続く場合は「\/\/」のようになる。
 エスケープ文字として使われる文字を文字通りの文字として表現するたの表記法必要である。例えば、HTMLではエスケープ文字である「&」を文字通りの文字として表現するために「&amp;」という表記法がある。またC言語ではエスケープ文字である「\」を文字通りの文字として表現するために「\\」という表記法がある。
 入力するのは簡単だが、その言語をよく知らない人によって理解ができなくなるp. 11。

エスケープシーケンス
エスケープシーケンスはエスケープ文字と似ているが、衝突する文字そのものの代わりに別の文字列を使用する。

例えば、Perlにおいて文字列リテラルの中にダブルクォートを含ませたいとき、以下のように書く。
print "Nancy said \x22Hello World!\x22 to the crowd.";  ### ダブルクォートの代わりにエスケープシーケンス \x22 を使用

エスケープ文字を使うと以下のようになる。
print "Nancy said \"Hello World!\" to the crowd.";      ### エスケープ文字を使用

エスケープシーケンスの欠点は、それぞれの文字を意味するコードを覚える必要があることである（文字参照を参照）。

2種類の区切り文字
2種類の区切り文字は、区切り文字衝突を避けるためのエスケープ文字やエスケープシーケンスとは別の手段を提供する。いくつかの言語では、シングルクォート (') とダブルクォート (") の2種類を文字列リテラルの区切り文字として使えるようになっている。

Perlでは以下のようになる。
print 'Nancy said "Hello World!" to the crowd.';
このように、エスケープを使わずに表現でき、可読性やコードを覚えなければいけない問題が解決する。しかしこの方法は、文字列が「両方の」種類の文字を含む場合には使えない。

区切り文字の繰り返し
区切り文字衝突を避けるためのエスケープ文字やエスケープシーケンスとは別の手段として、区切り文字の繰り返しがある。これは、衝突する文字を重ねて書く方法である。例えば、区切り文字にダブルクォートを用いるVisual Basicでは、次のようになる。区切り文字の繰り返しは、区切り文字のエスケープと似ている。
print "Nancy said ""Hello World!"" to the crowd."
文字列リテラル内のダブルクォートを2回続けて書くことで、区切り文字でないことを示している。2種類の区切り文字同様、エスケープを使わずに表現できる。しかし、複数のクォートが連続して現れる場合には可読性が低くなる。例えば、上記のソースコード自体を表示させたい場合は、以下のようになる。
print "print ""Nancy said """"Hello World!"""" to the crowd."""

3種類以上の区切り文字
2種類の区切り文字は2種類の範囲指定区切り文字を使用したが、3種類以上の区切り文字はその種類をさらに増やす。

以下はPerlでの例である。
print qq^Nancy doesn't want to say "Hello World!" anymore.^;
print qq@Nancy doesn't want to say "Hello World!" anymore.@;
print qq(Nancy doesn't want to say "Hello World!" anymore.);

いずれも、クォート演算子を用いることにより、意図した通りの出力がされる。どんな文字でも区切り文字の働きをさせることができる。この方法がより柔軟であるが、ほとんどの言語は対応していない。PerlとRubyは対応している In Ruby, these are indicated as general delimited strings. p. 11。

コンテントバウンダリ
コンテントバウンダリ (content boundary) は、マルチパートのメッセージにおいて、メッセージ中に現れないような文字列をパートの区切り文字として指定する方法である p. 26。

区切り文字は通常、統計学的に本文中に現れそうにないランダムな文字列から生成する。この後に、特定可能なマーク（UUID、タイムスタンプなど）が続く場合もある。区切り文字が本当に本文中に現れていないか確認することもある。この手法は、区切り文字を短かく、単純なものにすることができ、人間による可読性も向上する。（MIME、ヒアドキュメントも参照）

空白・インデント
いくつかのプログラミング言語やコンピュータ用言語では、テキスト中の独立した領域の境界を指定する手段として、空白文字による区切り文字やインデントが使用可能である Describes whitespace delimiters. p. 258.。

 正規表現の文法 

正規表現を指定する際、Perlで「マッチ（一致）」と「置換」のために構文を単純化するのに代替の区切り文字が用いられる page 472.。

例えば、Perlでの単純なマッチの操作の構文は以下のようになる。
$string1 = 'Nancy said "Hello World!" to the crowd.';    # 対象の文字列を指定
print $string1 =~ m/[aeiou]+/;                           # 1つ以上の母音にマッチ

この構文は、区切り文字の衝突を避けるために、区切り文字を柔軟に変更できる。
$string1 = 'Nancy said "http://Hello/World.htm" is not a valid address.'; # 対象の文字列を指定

print $string1 =~ m@http://@;       # 代替の区切り文字を使用したマッチ
print $string1 =~ m{http://};       # 別の区切り文字を使用。上と同じ結果になる。
print $string1 =~ m!http://!;       # 別の区切り文字を使用。上と同じ結果になる。

 ヒアドキュメント 

ヒアドキュメントは、特別な終了文字列を指定することによって、任意の内容が含められるようにしている。PHP、Bash、Perlなどの多くの言語が対応している。ヒアドキュメントは、終了文字列の指定から始まり、改行の後、終了文字列が現れるまで続くPerl operators and precedence。

以下はPerlによる例である。
print <<ENDOFHEREDOC;
It's very hard to encode a string with "certain characters".

Newlines, commas, and other characters can cause delimiter collisions.
ENDOFHEREDOC

上記のコードを実行すると、以下のように出力される。
 It's very hard to encode a string with "certain characters".

 Newlines, commas, and other characters can cause delimiter collisions.

内容には、（終了文字列そのもの以外は）どんな文字でも含めることができる。

ASCII-armor
主にバイナリデータのテキスト・エンコーディングのためのメカニズムとして使われるが、ASCII-armorは、いくつかの状況で区切り文字の衝突を避けるためにも使えるプログラミングとシステム管理のテクニックである(an example usage of ASCII armoring in encryption applications)(an example usage of ASCII armoring in encryption applications)。

この手法は複雑なため、小さなアプリケーションと単純なデータ記憶フォーマットにふさわしくない。区切り文字が送られたデータで現れないことを確実とするために、特別なエンコーディング・スキーム（例えばbase64）を使用する。

この手法はマイクロソフトのASP.NETなどで使われており、そのシステムの"VIEWSTATE"コンポーネントと密接に関係している(describes the use of Base64 encoding and VIEWSTATE inside HTML source code)。

 例 
以下の簡略化された例は、この技術が実際にはどのように機能するかについて示す。

次のコード断片は、VIEWSTATEの値がHTMLタグの区切り文字 (") と衝突する例である。このコードは"Well-formed"ではなく、正しく解釈されない。
<input type="hidden" name="__VIEWSTATE" value="BookTitle:Nancy doesn't say "Hello World!" anymore." />

次のコード断片は同じHTMLタグを示しているが、VIEWSTATEの値をbase64でエンコードすることによって、区切り文字と衝突する文字が取り除かれている。
<input type="hidden" name="__VIEWSTATE" value="Qm9va1RpdGxlOk5hbmN5IGRvZXNuJ3Qgc2F5ICJIZWxsbyBXb3JsZCEiIGFueW1vcmUu" />

次のコード断片は、同じHTMLタグをパーセントエンコーディングによって表した例である。
<input type="hidden" name="__VIEWSTATE" value="BookTitle:Nancy%20doesn%27t%20say%20%22Hello%20World!%22%20anymore." />

どんな文字がオリジナルの（デコードされた）テキストに現れるかに関係なく、この手法は区切り文字の衝突を防止し、非互換の文字がHTMLコードに現れないことを確実にする。
配列変換
区切り文字としたい文字列中に存在しない文字を特定してその文字を区切り文字とし、区切り文字とした文字が何であるかを決められた位置（例えば、１文字目とか、最後の位置）に配置する。
例えば、「\10,000」「\300」「aaa;」という文字列がある場合、カンマやセミコロンは区切り文字にならないから、それらの文字列中に存在しない文字、例えば「>」を区切り文字とし、「>\10,000>\300>aaa;>」とする。日本国特許第6511598号

関連項目


 エスケープシーケンス

出典

外部リンク
 Data File Metaformats from  by Eric Steven Raymond

Category:文字列
Category:プログラミング言語の構文
Category:マークアップ言語