16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"文字列からトークン切り出し(StrTok)"
この発言に対し以下のコメントが寄せられています
#00630 DUDE さん RE:文字列からトークン切り出し(StrTok)
いや、文字列操作に strtok 関数がないのでは困る、とお嘆きの貴兄に StrTok 関数
シリーズをお贈りします。
Cでは、strtok 1本で、最初のトークン切り出しと、2番目以降のトークン切り出
しの両方をまかなっていますが、マルチスレッド環境では使えないので、ここでは
TStrTokRec 構造体を導入して、スレッドセーフにしています。
単発で、文字列の最初や最後のトークンを切り出すだけなら StrTok 関数や
StrTokLast 関数を使います。頭から順番に、一個ずつ連続してトークンを取り出す
場合は、StrTokFirst 関数、StrTokNext 関数を使います。
いずれの関数も、トークンが存在しない場合は空の文字列を返します。
利用方法は、例を見てください。
interface
type
TStrTokSeparator = set of Char;
TStrTokRec = record
Str:string;
Pos:Integer;
end;
function StrTok(const s:string; const Sep:TStrTokSeparator):string;
function StrTokLast(const s:string; const Sep:TStrTokSeparator):string;
function StrTokFirst(const s:string; const Sep:TStrTokSeparator; var
Rec:TStrTokRec):string;
function StrTokNext(const Sep:TStrTokSeparator; var Rec:TStrTokRec):string;
implementation
{ 文字列からトークンの切り出し(単発処理) }
function StrTok(const s:string; const sep:TStrTokSeparator):string;
var
Rec:TStrTokRec;
begin
Rec.Str := s;
Rec.Pos := 1;
Result := StrTokNext(Sep, Rec);
end;
{ 文字列からトークンの切り出し(単発処理) }
function StrTokLast(const s:string; const sep:TStrTokSeparator):string;
var
Rec:TStrTokRec;
ss:string;
begin
Result := '';
ss := StrTokFirst(s, Sep, Rec);
repeat
Result := ss;
ss := StrTokNext(Sep, Rec);
until ss = '';
end;
{ 文字列からトークンの切り出し(初期処理) }
function StrTokFirst(const s:string; const sep:TStrTokSeparator; var
Rec:TStrTokRec):string;
begin
Rec.Str := s;
Rec.Pos := 1;
Result := StrTokNext(sep, Rec);
end;
{ 文字列からトークンの切り出し }
function StrTokNext(const sep:TStrTokSeparator; var Rec:TStrTokRec):string;
var
Len:Integer;
s:string;
begin
with Rec do
begin
Len := Length(Str);
Result := '';
if Len >= Pos then
begin
while (Pos <= Len) and (Str[Pos] in sep) do // 漢字の1バイト目はマッ
チしないのでチェック不要
begin
Inc(Pos);
end;
while (Pos<= Len) and not (Str[Pos] in sep) do
begin
Result := Result + Str[Pos];
if IsDBCSLeadByte(Byte(Str[Pos])) then
begin
Inc(Pos);
Result := Result + Str[Pos];
end;
Inc(Pos);
end;
while (Pos <= Len) and (Str[Pos] in sep) do // 漢字の1バイト目は
マッチしないのでチェック不要
begin
Inc(Pos);
end;
end;
end;
end;
const line:string = '1,PFF01344,DUDE,FDELPHI';
var s:string;
s := StrTok(line,[',']); // s には '1' が入る
s := StrTokLast(line,[',']); // s には 'FDELPHI' が入る
const line:string = ' Hello, world! ';
var s:string, Rec:TStrTokRec;
s := StrTokFirst(line,[',',' '],Rec); // s には 'Hello' が入る
s := StrTokNext([',',' '],Rec); // s には 'world!' が入る
注) StrTokNext 関数は、毎回セパレータを登録できるので、途中からセパレータを
変更することが可能です。
98/8/18(Tue) 09:45am [AirCraft 97開発] PFF01344 DUDE
Original document by DUDE 氏 ID:(PFF01344)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|