作成中のシステム(サイトビルダー)に最適なデリミタを考えてみる。
ここで言うデリミタの定義は…
「システムで予約された特別な文字(列)です。
デリミタは文字列の中に埋め込まれて使用されます。
パーサがデリミタに反応し特別な処理を行います。」
デリミタは、/のように一文字で表されることもありますが、
<と>のように左右対でも有効です。
例えば、
・HTMLのデリミタは、<と> です。
・CSVのデリミタは、"と" や TAB や , などです。
今回考えなければいけないデリミタの条件は以下の通りです。
ちょっと条件大盛な気がしますが、順を追って考えてみます。
※ 一部の記号がBLOG上でサニタイズ(消去)されないように全角にしています。
条件1. キーボードから入力可能でプリンタブルな文字列
条件2. SJISとUTF-8で相互変換しても安全な文字列
条件3. デリミタは二文字の文字列。
条件4. 文字列の中に埋め込んで使用するため、左右で対となる文字列
条件5. サニタイズ対象とならない文字列。実体参照が定義されていない文字列。
条件6. 入力ミスが発生しづらい、つまり判りやすい文字列であること。
条件7. 一般的な文書やソースコードで見かけない文字列であること。
条件8. 経験上もソースコード内に記述した組み合わせは避けること。
条件9. Google先生に審査してもらうこと。
■条件1から有効な文字列要素は、
!”#$%&’()*+,-./:;<=>?@[¥]^_‘{|} ̄
と 数字と英字 となります。
■ 条件2と3から有効な文字(列)要素は、
デリミタの一文字目は、
SJISの二バイト目に現れる文字列(つまり0x40~0x7E)はダメ。
UNICODEのコードマップの違いを考慮すると、
全角化⇔半角化を繰り返した場合に誤変換される可能性の高い
~と- は使用できない文字となります。
さらに、一文字目からは英数字を除外します。
適当な組み合わせは、
一文字目に使用可能な文字列:
!”#$%&’()*+,./:;<=>?
二文字目に使用可能な文字列
!”#$%&’()*+,./:;<=>?@[¥]^_‘{|}
となります。
■ 条件4で、文字列に埋め込んで使用する左右対の文字列である必要があるため
ダブルクォートとシングルクォートといったクォート用の文字、
またエスケープシーケンスに使用される文字(¥)は除外する必要があります。
さらに、一文字目から対にならない記号を除外します。
適当な組み合わせは、
一文字目に使用可能な文字列:
()<>
二文字目に使用可能な文字列
!#$%&()*+,./:;<=>?@[]^_{|}
となります。
■ 条件5で、サニタイズ対象とならない文字列と
実体参照が定義されていない文字列(^~”’<>&は定義済み)とありますので、
適当な組み合わせは、
一文字目に使用可能な文字列:
()
二文字目に使用可能な文字列
!#$%()*+,./:;=?@[]_{|}
となります。
■ 条件6で、入力ミスが発生しづらい、つまり判りやすい文字列であること、
とありますので、フォント依存で変形しやすい文字(l10o)や、
見間違えやすい文字(,._-|:;)は除外します。
文字化けした場合に特定環境で表示されることのある?も除外します。
英数字も対象外とします。
適当な組み合わせは、
一文字目に使用可能な文字列:
()
二文字目に使用可能な文字列
!#$%()*+/=@[]{}
となります。
ここまでに残った文字で、総当りを作ってみます。
BEGIN END
(! !)
(# #)
($ $)
(% %)
(( ()
() ))
(* *)
(+ +)
(/ /)
(= =)
(@ @)
([ [)
(] ])
({ {)
(} })
# なんか顔文字みたいになってますが…
■条件7で、一般的な文書やソースコードで見かけない文字列であること、
とありますので、ソースコードで多用されるフレーズは除外します。
パッと思いつくフレーズとしてはこんな感じです。
数式: z = ((a + b) * c) / 10; ⇒ (( はダメ
ソースコード: if(!var) ⇒ (! はダメ
ソースコード: (var[i]) ⇒ ]) はダメ
PHPのソースコード: if($var) ⇒ ($ はダメ
PHPのソースコード: if(@func()) ⇒ (@ はダメ
正規表現のメタキャラ: ($1) ⇒ ($ はダメ
正規表現のメタキャラ: (?) ⇒ (? はダメ
正規表現のメタキャラ: (*) ⇒ (* はダメ
正規表現のメタキャラ: (+) ⇒ (+ はダメ
正規表現のメタキャラ: (.) ⇒ (. はダメ
正規表現のメタキャラ: (+{1}) ⇒ }) はダメ
「今年のxxは120%(昨年は100%)」 といった文章に登場しそうな ⇒ %) はダメ
残る適当な組み合わせは、
(# と #)
(/ と /)
(= と =)
■ 条件8. 経験上もソースコード内に記述した組み合わせは避けること。
扱ったことのある言語(XHTML,C,C++,Delphi,Peal,Javascript,VB,PHP,ASP,SQL)で
これらの文字列の組み合わせは登場しませんでしたが、
#) が次の行の先頭に現れた場合に、スクリプト等でコメント行として扱われる懸念があるため除外します。
/) は URLなどのパス関係で使用すると、まずそうですので除外します。
残る適当な組み合わせは、
(= と =)
となります。
(= =) はドラえもんやキティの顔文字で多用【?】されるようですが、
顔文字やAAを考慮すると全ての記号が使えないことになりますし、
一般的なビジネス文書では顔文字は登場しませんので除外対象としません。
■ 条件9で、Google先生に審査してもらうこと、とありますので、
Google先生に (= =) を聞いて回ります。
その結果は、(が正規表現のORに該当する文字のため、
全てゼロ件ヒット…というか検索が実行されない。
三時間ほど(BLOGを書く時間込み)熟考の結果…
(= =) を使用しても、まぁ問題は無いでしょうと。
ということで、今回のシステムでは、
(= と =) を使用することにします。
ここで言うデリミタの定義は…
「システムで予約された特別な文字(列)です。
デリミタは文字列の中に埋め込まれて使用されます。
パーサがデリミタに反応し特別な処理を行います。」
デリミタは、/のように一文字で表されることもありますが、
<と>のように左右対でも有効です。
例えば、
・HTMLのデリミタは、<と> です。
・CSVのデリミタは、"と" や TAB や , などです。
今回考えなければいけないデリミタの条件は以下の通りです。
ちょっと条件大盛な気がしますが、順を追って考えてみます。
※ 一部の記号がBLOG上でサニタイズ(消去)されないように全角にしています。
条件1. キーボードから入力可能でプリンタブルな文字列
条件2. SJISとUTF-8で相互変換しても安全な文字列
条件3. デリミタは二文字の文字列。
条件4. 文字列の中に埋め込んで使用するため、左右で対となる文字列
条件5. サニタイズ対象とならない文字列。実体参照が定義されていない文字列。
条件6. 入力ミスが発生しづらい、つまり判りやすい文字列であること。
条件7. 一般的な文書やソースコードで見かけない文字列であること。
条件8. 経験上もソースコード内に記述した組み合わせは避けること。
条件9. Google先生に審査してもらうこと。
■条件1から有効な文字列要素は、
!”#$%&’()*+,-./:;<=>?@[¥]^_‘{|} ̄
と 数字と英字 となります。
■ 条件2と3から有効な文字(列)要素は、
デリミタの一文字目は、
SJISの二バイト目に現れる文字列(つまり0x40~0x7E)はダメ。
UNICODEのコードマップの違いを考慮すると、
全角化⇔半角化を繰り返した場合に誤変換される可能性の高い
~と- は使用できない文字となります。
さらに、一文字目からは英数字を除外します。
適当な組み合わせは、
一文字目に使用可能な文字列:
!”#$%&’()*+,./:;<=>?
二文字目に使用可能な文字列
!”#$%&’()*+,./:;<=>?@[¥]^_‘{|}
となります。
■ 条件4で、文字列に埋め込んで使用する左右対の文字列である必要があるため
ダブルクォートとシングルクォートといったクォート用の文字、
またエスケープシーケンスに使用される文字(¥)は除外する必要があります。
さらに、一文字目から対にならない記号を除外します。
適当な組み合わせは、
一文字目に使用可能な文字列:
()<>
二文字目に使用可能な文字列
!#$%&()*+,./:;<=>?@[]^_{|}
となります。
■ 条件5で、サニタイズ対象とならない文字列と
実体参照が定義されていない文字列(^~”’<>&は定義済み)とありますので、
適当な組み合わせは、
一文字目に使用可能な文字列:
()
二文字目に使用可能な文字列
!#$%()*+,./:;=?@[]_{|}
となります。
■ 条件6で、入力ミスが発生しづらい、つまり判りやすい文字列であること、
とありますので、フォント依存で変形しやすい文字(l10o)や、
見間違えやすい文字(,._-|:;)は除外します。
文字化けした場合に特定環境で表示されることのある?も除外します。
英数字も対象外とします。
適当な組み合わせは、
一文字目に使用可能な文字列:
()
二文字目に使用可能な文字列
!#$%()*+/=@[]{}
となります。
ここまでに残った文字で、総当りを作ってみます。
BEGIN END
(! !)
(# #)
($ $)
(% %)
(( ()
() ))
(* *)
(+ +)
(/ /)
(= =)
(@ @)
([ [)
(] ])
({ {)
(} })
# なんか顔文字みたいになってますが…
■条件7で、一般的な文書やソースコードで見かけない文字列であること、
とありますので、ソースコードで多用されるフレーズは除外します。
パッと思いつくフレーズとしてはこんな感じです。
数式: z = ((a + b) * c) / 10; ⇒ (( はダメ
ソースコード: if(!var) ⇒ (! はダメ
ソースコード: (var[i]) ⇒ ]) はダメ
PHPのソースコード: if($var) ⇒ ($ はダメ
PHPのソースコード: if(@func()) ⇒ (@ はダメ
正規表現のメタキャラ: ($1) ⇒ ($ はダメ
正規表現のメタキャラ: (?) ⇒ (? はダメ
正規表現のメタキャラ: (*) ⇒ (* はダメ
正規表現のメタキャラ: (+) ⇒ (+ はダメ
正規表現のメタキャラ: (.) ⇒ (. はダメ
正規表現のメタキャラ: (+{1}) ⇒ }) はダメ
「今年のxxは120%(昨年は100%)」 といった文章に登場しそうな ⇒ %) はダメ
残る適当な組み合わせは、
(# と #)
(/ と /)
(= と =)
■ 条件8. 経験上もソースコード内に記述した組み合わせは避けること。
扱ったことのある言語(XHTML,C,C++,Delphi,Peal,Javascript,VB,PHP,ASP,SQL)で
これらの文字列の組み合わせは登場しませんでしたが、
#) が次の行の先頭に現れた場合に、スクリプト等でコメント行として扱われる懸念があるため除外します。
/) は URLなどのパス関係で使用すると、まずそうですので除外します。
残る適当な組み合わせは、
(= と =)
となります。
(= =) はドラえもんやキティの顔文字で多用【?】されるようですが、
顔文字やAAを考慮すると全ての記号が使えないことになりますし、
一般的なビジネス文書では顔文字は登場しませんので除外対象としません。
■ 条件9で、Google先生に審査してもらうこと、とありますので、
Google先生に (= =) を聞いて回ります。
その結果は、(が正規表現のORに該当する文字のため、
全てゼロ件ヒット…というか検索が実行されない。
三時間ほど(BLOGを書く時間込み)熟考の結果…
(= =) を使用しても、まぁ問題は無いでしょうと。
ということで、今回のシステムでは、
(= と =) を使用することにします。