区切り文字英語: delimiter、デリミタ)は、コンピュータ言語やデータ通信において独立した領域の境界を特定するために入れられる文字である[1]。例えば、コンマ区切りの文字列において、コンマ ( 区切り文字は、データストリームで境界を指定する方法の1つである。別の方法として、各フィールドの先頭にフィールド長を記述する方法もある[2]。 概要区切り文字は以下の2種類に分けられる。
フィールド区切り文字・レコード区切り文字フィールド区切り文字はデータフィールドを分離し、レコード区切り文字はフィールドのグループを分離する[3]。 例えば、CSVファイルはコンマをフィールド間の区切り文字として、改行コードをレコード間の区切り文字として使用している。 以下は、CSVファイルのフォーマットを使用した簡単なフラットファイルデータベースのテーブルの例である。 fname,lname,age,salary
nancy,davolio,33,$30000
erin,borakova,28,$25250
tony,raphael,35,$28700
範囲指定区切り文字範囲指定区切り文字は、テキストの範囲の最初と最後を示すものである[4][5]。 よく使われる範囲指定区切り文字には、以下のものがある[6]。
慣習慣習的に、プラットフォームによって特定の区切り文字が使われる[14]。以下に、そのいくつかの例を示す。 プログラミング言語 (プログラミング言語の比較 (文法)も参照)
フィールド区切り文字・レコード区切り文字(ASCII、制御文字も参照)
区切り文字衝突区切り文字衝突(英語: delimiter collision)とは、テキスト中のある文字が区切り文字として解析され、意図しない動作を引き起こす問題である[3][16]。例えばCSVファイルの場合、フィールドにコンマを含む値(例: 悪意のあるユーザーや攻撃者は、この問題を故意に利用しようとするかもしれない。従って、区切り文字衝突は、セキュリティホールやエクスプロイトの原因となり得る。悪意のあるユーザーはSQLやHTMLのような言語で、区切り文字衝突を利用してSQLインジェクションやクロスサイトスクリプティングのような攻撃を行う。 解決法区切り文字衝突は非常に一般的な問題なので、それを回避する様々な方法が考案されている。 データストリームに現れそうにない文字(または文字列)を区切り文字として選ぶことによって、問題を回避する方法がある。この方法は多くの場合は通用するが、その文字がデータストリームに現れる確率はゼロではなく、また、悪意のある攻撃に対して安全ではない。よって、この方法は通常はとられない。 ASCII制御文字ASCIIとUnicodeの文字セットではこの問題を回避するために、区切り文字として使用するための非表示の制御文字を用意している。それらの文字はASCIIで28 (0x1C) から31 (0x1F) に割り当てられている。
ASCII 31のユニット分離文字をフィールド区切り文字として、ASCII 30のレコード分離文字をレコード区切り文字として使用することで、フィールド区切り文字・レコード区切り文字の問題は解決する[17]。 エスケープ文字区切り文字衝突の他の解決法として、エスケープ文字を使用する方法がある。これは、区切り文字の前にエスケープ文字を置くことで、その文字は区切り文字として使用する意図ではないことを明示するものである。言語設計の見地からはこれで十分であるが、以下のような欠点もある。
エスケープシーケンスエスケープシーケンスはエスケープ文字と似ているが、衝突する文字そのものの代わりに別の文字列を使用する。 例えば、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種類以上の区切り文字はその種類をさらに増やす[19]。 以下は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は対応している[20][21]。 コンテントバウンダリコンテントバウンダリ (content boundary) は、マルチパートのメッセージにおいて、メッセージ中に現れないような文字列をパートの区切り文字として指定する方法である[22]。 区切り文字は通常、統計学的に本文中に現れそうにないランダムな文字列から生成する。この後に、特定可能なマーク(UUID、タイムスタンプなど)が続く場合もある。区切り文字が本当に本文中に現れていないか確認することもある。この手法は、区切り文字を短かく、単純なものにすることができ、人間による可読性も向上する。(MIME、ヒアドキュメントも参照) 空白・インデントいくつかのプログラミング言語やコンピュータ用言語では、テキスト中の独立した領域の境界を指定する手段として、空白文字による区切り文字やインデントが使用可能である[23]。 正規表現の文法→「正規表現」も参照
正規表現を指定する際、Perlで「マッチ(一致)」と「置換」のために構文を単純化するのに代替の区切り文字が用いられる[24]。 例えば、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などの多くの言語が対応している。ヒアドキュメントは、終了文字列の指定から始まり、改行の後、終了文字列が現れるまで続く[25]。 以下は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は、いくつかの状況で区切り文字の衝突を避けるためにも使えるプログラミングとシステム管理のテクニックである[26][27]。 この手法は複雑なため、小さなアプリケーションと単純なデータ記憶フォーマットにふさわしくない。区切り文字が送られたデータで現れないことを確実とするために、特別なエンコーディング・スキーム(例えばbase64)を使用する。 この手法はマイクロソフトのASP.NETなどで使われており、そのシステムの"VIEWSTATE"コンポーネントと密接に関係している[28]。 例以下の簡略化された例は、この技術が実際にはどのように機能するかについて示す。 次のコード断片は、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コードに現れないことを確実にする。 配列変換区切り文字としたい文字列中に存在しない文字を特定してその文字を区切り文字とし、区切り文字とした文字が何であるかを決められた位置(例えば、1文字目とか、最後の位置)に配置する。 関連項目出典
外部リンク |