■御題
いま、カンマ区切りのファイルがあったとしよう。
abcdefg,123,fghijk
ここで、abcdefgが入っている1桁目は、
カンマも入力できるとする。
abc,defg,123,fghijk
そうすると、,のところで分解すると、abcとdefgと分かれてしまう
もちろん、""で囲って、"abc,defg",123,fghijkとなっても、
abcとdefgで分かれてしまう。
そこで、
・,のところで分解する
・文字中に,が入っても大丈夫
・置換だけで、実現したい
場合、どのようにすると、実現できるか?というお話
■実現方法
実現方法としては、コード変換とエスケープがある
(ここでは、abcdefgの項目を最後にもって行き、ある個数以上
,がきたら連結するという回答は、除外する。それだと、
2項目(abcdefgとfghijk等)以上で,を許したら、できなくなってしまう)
コード変換の場合は、出来ることは自明だろう。
たとえば、すべての項目を16進に変換する。
そうすれば、
現れる文字は0123456789abcdefだけだから、
項目区切りに,が使える
実務上では、URLエンコーディング、base64などが使えそうだ。
まあ、ここでは、それ以上触れない。
一方、エスケープだが、これは、出来る場合と出来ない場合がある
それについて、少し書く。
■エスケープの手法
ここで、エスケープの手法をまず定義する。
今回、,の文字を回避したい。
●この回避したい文字を、
ターゲット文字とよぶことにする。
今回の場合,(カンマ)
●このとき、ターゲット文字とは違うある文字を選び
(これをエスケープ文字と呼ぼう、
今回は、これを%とする)
●文中に、エスケープ文字やターゲット文字が来たとき、
エスケープ文字+他の文字で表す
ことを、エスケープと呼ぼう。
つまり、
abc%de,fg
とあった場合、%と,を別の文字に変える手法をさす
そして、ここで
■エスケープの手法3つ
このとき、エスケープの手法としては、大きく分けて3つある
なお、以下、%をエスケープ文字、,をターゲット文字とする
<<手法1>>
%を%%
,を%,
であらわす。つまり、
エスケープ文字=エスケープ文字+エスケープ文字
ターゲット文字=エスケープ文字+ターゲット文字
にする。上記「エスケープ文字+他の文字」
のほかの文字を左辺(=の手前)の文字にすることである。
この方法でabc%de,fgを変換すると、abc%%de%,fgとなる。
この方法では
1文字づつ読み込んで、%が来たら、次の文字をそのまま出す
という方法であれば、変換できるが、
そもそも、,で項目を切れない(abc%%de%とfgの間の,で2つに切れてしまう)。
<<手法2>>
%を%%
,を%d
であらわす。つまり、
エスケープ文字=エスケープ文字+エスケープ文字
ターゲット文字=エスケープ文字+他の文字
にする。上記「エスケープ文字+他の文字」
の「他の文字」をターゲット文字の場合、
ターゲットでもエスケープでもない文字にする
この方法でabc%de,fgを変換すると、abc%%de%dfgとなる。
この方法でなら、,はきえるので1項目となり、
,で項目を区切ることはできる。
しかし、変換をするとき、
●,(%d)を先に変換し%(%%)を後から変換すると
abc%%de%dfg→abc%,e,fg→abc%,e,fg(%%はないので、置換できない)
となり、もとのabc%de,fgと一致しない
●%(%%)を先に変換し,(%,)を後から変換すると
abc%%de%dfg→abc%de%dfg→abc,e,fg
となり、もとのabc%de,fgと一致しない
<<手法3>>
%を%c
,を%d
であらわす。つまり、
エスケープ文字=エスケープ文字+他の文字1
ターゲット文字=エスケープ文字+他の文字2
にする。上記「エスケープ文字+他の文字」
の「他の文字」をターゲット文字もエスケープ文字も別の文字にする
この方法でabc%de,fgを変換すると、abc%cde%dfgとなる。
この方法でなら、,はきえるので1項目となり、
,で項目を区切ることはできる。
そして置換された文字列を
●,(%d)を先に変換し%(%c)を後から変換すると
abc%cde%dfg→abc%cde,fg→abc%de,fg
となって、元に戻る
ちなみに、置換するときは
○%(%c)を先に変換し,(%d)を後から変換する
abc%de,fg→abc%cde,fgやじるsabc%cde%dfg
となり、置換できる
つまり、エスケープで行う場合には、<<手法3>>
(1)変換したい文字をきめ、ターゲット文字とする
今回は,
(2)エスケープ文字を決める(ターゲット文字以外)
今回は%
(3)ターゲット文字、エスケープ文字以外の2文字を決め、
それぞれ、他の文字1、他の文字2とする
今回は、他の文字1=c,他の文字2=d
(4)エンコーディングするときは
エスケープ文字=エスケープ文字+他の文字1
ターゲット文字=エスケープ文字+他の文字2
とすればよい。
具体的には、
元の文字に対して、
エスケープ文字を先に変換し,ターゲット文字を後から変換して
エスケープ文字列を得る
(5)エスケープ文字列にカンマなどをつけて、
所定の文字列にする
(6)解析するときは
(5)の文字列を、カンマなどで分解して、エスケープ文字列を得て
(7)エスケープ文字列に対して
ターゲット文字を先に変換し、エスケープ文字を後から変換すると
元の文字列を得る
■ちなみに
この仕組みと同じものが、HTMLの&と<
ターゲット <
エスケープ &
他の文字列1 amp;
他の文字列2 gt;
とすると、上記の話が成り立つ。
いま、カンマ区切りのファイルがあったとしよう。
abcdefg,123,fghijk
ここで、abcdefgが入っている1桁目は、
カンマも入力できるとする。
abc,defg,123,fghijk
そうすると、,のところで分解すると、abcとdefgと分かれてしまう
もちろん、""で囲って、"abc,defg",123,fghijkとなっても、
abcとdefgで分かれてしまう。
そこで、
・,のところで分解する
・文字中に,が入っても大丈夫
・置換だけで、実現したい
場合、どのようにすると、実現できるか?というお話
■実現方法
実現方法としては、コード変換とエスケープがある
(ここでは、abcdefgの項目を最後にもって行き、ある個数以上
,がきたら連結するという回答は、除外する。それだと、
2項目(abcdefgとfghijk等)以上で,を許したら、できなくなってしまう)
コード変換の場合は、出来ることは自明だろう。
たとえば、すべての項目を16進に変換する。
そうすれば、
現れる文字は0123456789abcdefだけだから、
項目区切りに,が使える
実務上では、URLエンコーディング、base64などが使えそうだ。
まあ、ここでは、それ以上触れない。
一方、エスケープだが、これは、出来る場合と出来ない場合がある
それについて、少し書く。
■エスケープの手法
ここで、エスケープの手法をまず定義する。
今回、,の文字を回避したい。
●この回避したい文字を、
ターゲット文字とよぶことにする。
今回の場合,(カンマ)
●このとき、ターゲット文字とは違うある文字を選び
(これをエスケープ文字と呼ぼう、
今回は、これを%とする)
●文中に、エスケープ文字やターゲット文字が来たとき、
エスケープ文字+他の文字で表す
ことを、エスケープと呼ぼう。
つまり、
abc%de,fg
とあった場合、%と,を別の文字に変える手法をさす
そして、ここで
■エスケープの手法3つ
このとき、エスケープの手法としては、大きく分けて3つある
なお、以下、%をエスケープ文字、,をターゲット文字とする
<<手法1>>
%を%%
,を%,
であらわす。つまり、
エスケープ文字=エスケープ文字+エスケープ文字
ターゲット文字=エスケープ文字+ターゲット文字
にする。上記「エスケープ文字+他の文字」
のほかの文字を左辺(=の手前)の文字にすることである。
この方法でabc%de,fgを変換すると、abc%%de%,fgとなる。
この方法では
1文字づつ読み込んで、%が来たら、次の文字をそのまま出す
という方法であれば、変換できるが、
そもそも、,で項目を切れない(abc%%de%とfgの間の,で2つに切れてしまう)。
<<手法2>>
%を%%
,を%d
であらわす。つまり、
エスケープ文字=エスケープ文字+エスケープ文字
ターゲット文字=エスケープ文字+他の文字
にする。上記「エスケープ文字+他の文字」
の「他の文字」をターゲット文字の場合、
ターゲットでもエスケープでもない文字にする
この方法でabc%de,fgを変換すると、abc%%de%dfgとなる。
この方法でなら、,はきえるので1項目となり、
,で項目を区切ることはできる。
しかし、変換をするとき、
●,(%d)を先に変換し%(%%)を後から変換すると
abc%%de%dfg→abc%,e,fg→abc%,e,fg(%%はないので、置換できない)
となり、もとのabc%de,fgと一致しない
●%(%%)を先に変換し,(%,)を後から変換すると
abc%%de%dfg→abc%de%dfg→abc,e,fg
となり、もとのabc%de,fgと一致しない
<<手法3>>
%を%c
,を%d
であらわす。つまり、
エスケープ文字=エスケープ文字+他の文字1
ターゲット文字=エスケープ文字+他の文字2
にする。上記「エスケープ文字+他の文字」
の「他の文字」をターゲット文字もエスケープ文字も別の文字にする
この方法でabc%de,fgを変換すると、abc%cde%dfgとなる。
この方法でなら、,はきえるので1項目となり、
,で項目を区切ることはできる。
そして置換された文字列を
●,(%d)を先に変換し%(%c)を後から変換すると
abc%cde%dfg→abc%cde,fg→abc%de,fg
となって、元に戻る
ちなみに、置換するときは
○%(%c)を先に変換し,(%d)を後から変換する
abc%de,fg→abc%cde,fgやじるsabc%cde%dfg
となり、置換できる
つまり、エスケープで行う場合には、<<手法3>>
(1)変換したい文字をきめ、ターゲット文字とする
今回は,
(2)エスケープ文字を決める(ターゲット文字以外)
今回は%
(3)ターゲット文字、エスケープ文字以外の2文字を決め、
それぞれ、他の文字1、他の文字2とする
今回は、他の文字1=c,他の文字2=d
(4)エンコーディングするときは
エスケープ文字=エスケープ文字+他の文字1
ターゲット文字=エスケープ文字+他の文字2
とすればよい。
具体的には、
元の文字に対して、
エスケープ文字を先に変換し,ターゲット文字を後から変換して
エスケープ文字列を得る
(5)エスケープ文字列にカンマなどをつけて、
所定の文字列にする
(6)解析するときは
(5)の文字列を、カンマなどで分解して、エスケープ文字列を得て
(7)エスケープ文字列に対して
ターゲット文字を先に変換し、エスケープ文字を後から変換すると
元の文字列を得る
■ちなみに
この仕組みと同じものが、HTMLの&と<
ターゲット <
エスケープ &
他の文字列1 amp;
他の文字列2 gt;
とすると、上記の話が成り立つ。