コンテンツにスキップ

区切り文字

出典: フリー百科事典『ウィキペディア(Wikipedia)』
CSVフォーマットのテキストファイルの一部の抜粋。赤色で示したコンマがフィールド区切り文字として使用されている。

英語: 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]

区切り文字 説明
( ... ) 丸括弧LISPの構文は、主に丸括弧を使用することで判別可能である[7]
{ ... } 波括弧[8]
[ ... ] 角括弧
< ... > 山括弧[9]
" ... " ダブルクォート文字列リテラルを表すのに使われる[10]
' ... ' シングルクォート。文字リテラルを表すのに使われる[10]
<? ... ?> XML処理命令英語版を表すのに使われる[11]
/* ... */ いくつかのプログラミング言語でコメントを表すのに使われる[12]
<% ... %> いくつかのWebテンプレートで言語の境界を特定するのに使用する。これは「テンプレート区切り文字」とも呼ばれる[13]

慣習

[編集]

慣習的に、プラットフォームによって特定の区切り文字が使われる[14]。以下に、そのいくつかの例を示す。

プログラミング言語プログラミング言語の比較 (文法)英語版も参照)

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

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

フィールドの終了レコードの終了ファイルの終了
Unix, OS X, Amiga OS タブLF(なし)
Windows, MS-DOS, OS/2, CP/M タブCRLFControl-Z[15]
Classic Mac OS, AppleDOS, ProDOS, GS/OS タブCR(なし)
ASCII/Unicode UNIT SEPARATOR
Position 31 (U+001F)
RECORD SEPARATOR
Position 30 (U+001E)
FILE SEPARATOR
Position 28 (U+001C)

区切り文字衝突

[編集]

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

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

解決法

[編集]

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

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

ASCII制御文字

[編集]

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

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

ASCII 31のユニット分離文字をフィールド区切り文字として、ASCII 30のレコード分離文字をレコード区切り文字として使用することで、フィールド区切り文字・レコード区切り文字の問題は解決する[17]

エスケープ文字

[編集]

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

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

エスケープシーケンス

[編集]

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

例えば、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://!;       # 別の区切り文字を使用。上と同じ結果になる。

ヒアドキュメント

[編集]

ヒアドキュメントは、特別な終了文字列を指定することによって、任意の内容が含められるようにしている。PHPBashPerlなどの多くの言語が対応している。ヒアドキュメントは、終了文字列の指定から始まり、改行の後、終了文字列が現れるまで続く[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文字目とか、最後の位置)に配置する。
例えば、「\10,000」「\300」「aaa;」という文字列がある場合、カンマやセミコロンは区切り文字にならないから、それらの文字列中に存在しない文字、例えば「>」を区切り文字とし、「>\10,000>\300>aaa;>」とする。[29]

関連項目

[編集]

出典

[編集]
  1. Federal Standard 1037C - Telecommunications: Glossary of Telecommunication Terms
  2. Rohl, Jeffrey S. (1973). Programming in Fortran. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-7190-0555-8 describing the method in Hollerith notation under the Fortran programming language.
  3. 1 2 de Moor, Georges J. (1993). Progress in Standardization in Health Care Informatics. IOS Press. ISBN 90-5199-114-2 p. 141
  4. Friedl, Jeffrey E. F. (2002). Mastering Regular Expressions: Powerful Techniques for Perl and Other Tools. O'Reilly. ISBN 0-596-00289-0 p. 319
  5. Scott, Michael Lee (1999). Programming Language Pragmatics. Morgan Kaufmann. ISBN 1-55860-442-1
  6. Wall; Larry; Jon Orwant (July 2000). Programming Perl (Third ed.). O'Reilly. ISBN 0-596-00027-8
  7. Kaufmann, Matt (2000). Computer-Aided Reasoning: An Approach. Springer. ISBN 0-7923-7744-3p. 3
  8. Meyer, Mark (2005). Explorations in Computer Science. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-7637-3832-7 references C-style programming languages prominently featuring curly brackets and semicolons.
  9. Dilligan, Robert (1998). Computing in the Web Age. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-306-45972-6Describes syntax and delimiters used in HTML.
  10. 1 2 Schwartz, Randal (2005). Learning Perl. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-596-10105-3Describes string literals.
  11. Watt, Andrew (2003). Sams Teach Yourself Xml in 10 Minutes. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-672-32471-0 Describes XML processing instruction. p. 21.
  12. Cabrera, Harold (2002). C# for Java Programmers. Oxford Oxfordshire: Oxford University Press. ISBN 978-1-931836-54-8 Describes single-line and multi-line comments. p. 72.
  13. Smarty Template Documentation”. 2010年3月12日閲覧。 See e.g., Smarty template system documentation, "escaping template delimiters".
  14. International Organization for Standardization (December 1, 1975). "The set of control characters for ISO 646". Internet Assigned Numbers Authority Registry. Alternate U.S. version: ASCII Graphic character set”. 2014年5月10日閲覧。. Accessed August 7, 2005.
  15. Lewine, Donald (1991). Posix Programmer's Guide. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-937175-73-6 Describes use of control-z. p. 156,
  16. Friedl, Jeffrey (2006). Mastering Regular Expressions. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-596-52812-6 describing solutions for embedded-delimiter problems p. 472.
  17. Discussion on ASCII Delimited Text vs CSV and Tab Delimited
  18. Kahrel, Peter (2006). Automating InDesign with Regular Expressions. O'Reilly. ISBN 0-596-52937-6p. 11
  19. Wall; Larry; Jon Orwant (July 2000). Programming Perl (Third ed.). O'Reilly. p. 63. ISBN 0-596-00027-8
  20. Wall; Larry; Jon Orwant (July 2000). Programming Perl (Third ed.). O'Reilly. p. 62. ISBN 0-596-00027-8
  21. Matsumoto, Yukihiro (2001). Ruby in a Nutshell. O'Reilly. ISBN 0-596-00214-9 In Ruby, these are indicated as general delimited strings. p. 11
  22. Javvin Technologies, Incorporated (2005). Network Protocols Handbook. Javvin Technologies Inc.. ISBN 0-9740945-2-8 p. 26
  23. 200, Cicling (2001). Computational Linguistics and Intelligent Text Processing. Oxford Oxfordshire: Oxford University Press. ISBN 978-3-540-41687-6 Describes whitespace delimiters. p. 258.
  24. Friedl, Jeffrey (2006). Mastering Regular Expressions. Oxford Oxfordshire: Oxford University Press. ISBN 978-0-596-52812-6 page 472.
  25. Perl operators and precedence
  26. Rhee, Man (2003). Internet Security: Cryptographic Principles, Algorithms and Protocols. John Wiley and Sons. ISBN 0-470-85285-2(an example usage of ASCII armoring in encryption applications)
  27. Gross, Christian (2005). Open Source for Windows Administrators. Charles River Media. ISBN 1-58450-347-5(an example usage of ASCII armoring in encryption applications)
  28. Kalani, Amit (2004). Developing and Implementing Web Applications with Visual C# . NET and Visual Studio . NET. Que. ISBN 0-7897-2901-6(describes the use of Base64 encoding and VIEWSTATE inside HTML source code)
  29. 日本国特許第6511598号

外部リンク

[編集]