†Sibylのお部屋†
作成開始日 2023.02.02
最終更新日 2023.02.02
DelphiではTStringListでTSVやCSVデータを扱うことができるようだが、SibylのTStringListには該当する機能がないようだ。ひょっとすると、データベース系のコンポーネントを使うと扱えるのかも知れないが、ここはごく単純に文字列処理で解決した。
基本的に、TSVデータを分解して、指定番目のデータ(文字列)を返す関数。区切りのタブ/スペースの個数は任意。データ中にスペースが含まれる場合には、当該データをシングルクォート「'」で括る。Pascal系なので文字列は「"」ではなく「'」で括る仕様(変更は簡単だと思う)。また、戻値に「'」は含まれないようにした。
//----------------------------------------------------------------------------- Function TForm1.SplitTSV(tsv:string; idx:Integer):String; //----------------------------------------------------------------------------- //TSV形式のデータを分解してn番目の項目を返す //CSV形式には対応していないが改造は難しくないだろう Var n,i : Integer; buf : String; flagS: Boolean; //区切りタブ/スペース・フラグ flagQ: Boolean; //シングルクォート・フラグ Begin flagS:=false; flagQ:=false; i:=1; //項目番号インジケーターを初期化 buf:=''; For n:=1 to Length(tsv) Do Begin If ((tsv[n]=' ')|(tsv[n]=#9))&(not flagQ) Then Begin if not flagS then inc(i); //区間の最初の区切り文字=次の項目に flagS:=true; //区切り区間であることを示すフラグ Continue; End; If i>idx Then Break; If tsv[n]=#$27 then //シングルクォート処理 Begin flagQ:=not flagQ; //クォート内か否かのトグルスイッチ Continue; //クォート文字は無視される End; If i=idx Then buf:=buf+tsv[n]; flagS:=false; //区切り区間ではない=データ区間 End; RESULT:=buf; END;使い方はこんな感じ…;なお、ソースの文字列中で「'」を使う場合は2つ重ねる。末尾で3つ重なるとエラーになるので、スペースを挟んでおく。ただし、ファイルから読み込む場合はこうした処理は不要、普通に「'」1つで括ればよい。
Var dat:String; st :String; Begin dat:='.JPG x:\tools\pmview.exe ''/WPos=(10,400,400,340,Res) $F'' '; st :=SplitTSV(dat,1); //戻値は「.JPG」 st :=SplitTSV(dat,2); //戻値は「x:\tools\pmview.exe」 st :=SplitTSV(dat,3); //戻値は「/WPos=(10,400,400,340,Res) $F」
//----------------------------------------------------------------------------- Procedure TForm1.SplitTSV2(tsv:string; sl:TStringList); //----------------------------------------------------------------------------- Var n,i : Integer; buf : String; flagS: Boolean; //区切りタブ/スペース・フラグ flagQ: Boolean; //シングルクォート・フラグ Begin flagS:=false; flagQ:=false; i:=1; buf:=''; sl.clear; sl.Add(tsv); //元データ(添字を1始まりにするための調整) For n:=1 to Length(tsv) Do Begin If ((tsv[n]=' ')|(tsv[n]=#9))&(not flagQ) Then Begin if not flagS then begin sl.add(buf); buf:=''; inc(i); end; flagS:=true; Continue; End; If tsv[n]=#$27 then //シングルクォート処理 Begin flagQ:=not flagQ; Continue; End; buf:=buf+tsv[n]; flags:=false; End; sl.add(buf); //これを忘れずに! END;使い方はこんな感じ…
Var sl : TStringList; //分解したデータを格納するリスト型変数 dat: String; //分解するTSVデータ extn, prog, parm: String; //データの各項目(拡張子、プログラム、引数) Begin dat:='.JPG x:\tools\pmview.exe ''/WPos=(10,400,400,340,Res) $F'' '; sl:=TStringList.Create; SplitTSV2(dat, sl); extn:=sl[1]; //「.JPG」([0]には元データが入れてある) prog:=sl[2]; //「x:\tools\pmview.exe」 parm:=sl[3]; //「/WPos=(10,400,400,340,Res) $F」 sl.Destroy;