(*----------------------------------- セパレータで文字を分解する処理 00/05/11 00/08/22 実装を丸ごと変更しました。 単語分解方法を幾つか選択出来るようにしたので ExcelのCSVファイルなど読むときも利用できます。 他にもDelimitersを引数指定するようにして使い勝手が上がっています。 00/08/25 Wordxxx2という関数名をWordxxxにしました 01/03/29 タブ文字の対応が出来ていなかったので修正 カンマ文字がDelimitersに含まれていない場合の処理を修正 WordCountとWordGetの内部ルーチンをWordDecomposerとして1つにまとめた 01/10/29 TWordDecomposeを実装 そのために無駄がないように function WordDecomposer に StringListを引数で渡すようにした 02/07/04 TWordDecomposeにIndexOfを実装した 2002/11/07 Split関数をStringUnitLightから移動 Split関数の内部を強化、WordDecomposerの内部処理をすべてまかす //-----------------------------------*) unit WordDecompose; interface uses // Types, SysUtils, StringUnitLight, XPtest; type TDecomposeMode = (dmUserFriendly, dmDelimiterExactly); {単語分解方法 UserFriendlyは区切り文字が複数個でも単語単位に分解 DelimiterExactlyは区切り文字に完全に正確に分解} function WordCount(const Delimiters, S: WideString; DecomposeMode: TDecomposeMode): Integer; function WordGet(const Delimiters, S: WideString; WordIndex: Integer; DecomposeMode: TDecomposeMode): WideString; type TWordDecompose = class(TObject) private FWords: TWideStringDynArray; FSentence: WideString; FDelimiters: WideString; function GetWords(Index: Integer): WideString; function GetCount: Integer; public constructor Create(const Delimiters, Sentence: WideString; Mode: TDecomposeMode); destructor Destroy; override; property Words[Index: Integer]: WideString read GetWords; property Count: Integer read GetCount; property Sentence: WideString read FSentence; property Delimiters: WideString read FDelimiters; function IndexOf(const Word: String; IgnoreCase: Boolean): Integer; end; {Create時に単語分解を行ってしまうクラス WordCount/WordGet毎に処理する無駄をはぶく} TSplitFlags = set of (sfIncludeDelimiter, sfEmptyStr); {↑sfIncludeDelimiter 分割時の戻り値に区切り文字自体も含まれる sfEmptyStr 空文字も分割したとみなす 例えば[A,B,]を分割する時[A][B][空文字]に分解される} function Split(const WideStr: WideString; const Delimiter: TWideStringDynArray; Flags: TSplitFlags): TWideStringDynArray; overload; function Split(const WideStr: WideString; const Delimiters: WideString; Flags: TSplitFlags): TWideStringDynArray; overload; procedure testSplit; implementation (*----------------------------------- //------------------------------- //連続スペース区切りを単一スペース区切りにする function ContinueDelimiterReplace(Delimiter, S: String): String; begin while AnsiPos(Delimiter + Delimiter, S) <> 0 do S := StringReplace(S, Delimiter + Delimiter, Delimiter, [rfReplaceAll]); Result := S; end; //-----------------------------------*) (*----------------------------------- {------------------------------- //Delimitersで指定した区切り文字群をCommaに置き換える処理 機能: 引数説明: Source:対象文字列 Delimiters:区切り文字列(例',/\;') 戻り値: カンマ区切りテキスト 備考: Commaが区切り文字に入っていない場合は テキスト中のCommaによって区切られるのを防ぐために Comma自体はタグに置き換えます。 履歴: 2001/03/29 //------------------------------} function ReplaceDelimiterToComma(Source: String; Delimiters: WideString): String; var i: Integer; begin Result := Source; if AnsiPos(',', Delimiters)=0 then begin {↑Delimiters中にコンマが存在しないのなら} Result := StringReplace(Result, ',', '%COMMA%', [rfReplaceAll]); end; for i := 1 to Length(Delimiters) do begin Result := StringReplace(Result, Delimiters[i], ',', [rfReplaceAll]); end; end; //%COMMA%タグを普通のCommaに戻します function ReturnDelimiterToComma(Source: String; Delimiters: WideString): String; begin Result := Source; if AnsiPos(',', Delimiters)=0 then begin {↑Delimiters中にコンマが存在しないのなら} Result := StringReplace(Result, '%COMMA%', ',', [rfReplaceAll]); end; end; //------------------------------ //-----------------------------------*) (*----------------------------------- {------------------------------- //StringList.CommaTextに代入するときに カンマだけの区切り方を行うための関数 機能: カンマ以外の区切られる文字列を排除しています 備考: SPACE/DOUBLE/TAB以外にも文字列があったら追加してください 履歴: 2001/03/29 //------------------------------} function TextToTrueSenseComma(const Text: String): String; var Str: String; begin Str := Text; {↓半角スペース及びダブルクウォーテーション、タブ文字 でCommaText区切りされてしまう対応策} Str := StringReplace(Str, ' ', '%SPACE%', [rfReplaceAll]); Str := StringReplace(Str, '"', '%DOUBLE%', [rfReplaceAll]); Str := StringReplace(Str, #9 , '%TAB%', [rfReplaceAll]); {↓カンマが最後に来る場合} if WideString(Str)[Length(WideString(Str))] = ',' then Str := Str + '%LAST%'; Result := Str; end; //置き換えられたタグを元に戻します function TrueSenseCommaToText(Text: String): String; begin Result := Text; Result := StringReplace(Result, '%SPACE%', ' ', [rfReplaceAll]); Result := StringReplace(Result, '%DOUBLE%', '"', [rfReplaceAll]); Result := StringReplace(Result, '%TAB%', '"', [rfReplaceAll]); Result := StringReplace(Result, '%LAST%', '', [rfReplaceAll]); end; //------------------------------ //-----------------------------------*) (*----------------------------------- {------------------------------- //単語区切り処理エンジン 引数説明: Delimiters:区切り文字列(例',/\;') S:対象文字列 WordIndex:取得したい単語のIndex 0から始まるIndex値 WordIndexが誤っている場合EmptyStrを戻す -1を設定すると単語を取得しない DeconposeMode:TDecomposeModeの定義参照 戻り値: 取得する文字列 Count:対象文字列に含まれる単語数 備考: 履歴: 2001/03/29 //------------------------------} function WordDecomposer(const Delimiters, S: WideString; WordIndex: Integer; DecomposeMode: TDecomposeMode; StringList: TStringList): String; var WideStr: WideString; begin Result := ''; if (Delimiters = '') or (S = '') then exit; WideStr := S; case DecomposeMode of dmUserFriendly: begin WideStr := ReplaceDelimiterToComma(WideStr, Delimiters); WideStr := ContinueDelimiterReplace(',', WideStr); {↓先頭と終端にカンマがあるのならトリムする} if WideStr[1] = ',' then begin Delete(WideStr, 1, 1); end; if WideStr[Length(WideStr)] = ',' then begin Delete(WideStr, Length(WideStr), 1); end; {↑ユーザーライクに単語を抽出する形式にする  例:『,,aaa,,a,bc,de,f,,』→『aaa,a,bc,de,f』にしている} end; dmDelimiterExactly: WideStr := ReplaceDelimiterToComma(WideStr, Delimiters); {↑区切り文字群をカンマに変換} dmExcelCSV: ; end; case DecomposeMode of dmUserFriendly, dmDelimiterExactly: begin StringList.CommaText := TextToTrueSenseComma(WideStr); if (0 <= WordIndex) and (WordIndex <= StringList.Count - 1) then Result := ReturnDelimiterToComma( TrueSenseCommaToText(StringList[WordIndex]) , Delimiters) else begin Result := ''; exit; end; end; dmExcelCSV: begin StringList.CommaText := WideStr; if (0 <= WordIndex) and (WordIndex <= StringList.Count - 1) then Result := StringList[WordIndex] else begin Result := ''; exit; end; end; end; end; //------------------------------ //-----------------------------------*) //------------------------------- //単語の数 //Delimitersに[,;:.]と指定すると //それぞれを区切り文字として認識して単語分解が行われる function WordCount(const Delimiters, S: WideString; DecomposeMode: TDecomposeMode): Integer; var WordDecompose1: TWordDecompose; begin WordDecompose1 := TWordDecompose.Create(Delimiters, S, DecomposeMode); try Result := WordDecompose1.Count; finally WordDecompose1.Free; end; end; //------------------------------- //{区切られた単語を番号で呼び出す //Delimitersに[,;:.]と指定すると //それぞれを区切り文字として認識して単語分解が行われる function WordGet(const Delimiters, S: WideString; WordIndex: Integer; DecomposeMode: TDecomposeMode): WideString; var WordDecompose1: TWordDecompose; begin WordDecompose1 := TWordDecompose.Create(Delimiters, S, DecomposeMode); try Result := WordDecompose1.Words[WordIndex]; finally WordDecompose1.Free; end; end; //////////////////////////////////////////////////////////// { TWordDecompose } //////////////////////////////////////////////////////////// constructor TWordDecompose.Create(const Delimiters, Sentence: WideString; Mode: TDecomposeMode); var DelimiterArray: TWideStringDynArray; i: Integer; begin {↓WideStringを1文字ずつ動的配列に展開} SetLength(DelimiterArray, Length(Delimiters)); for i := 0 to Length(Delimiters)-1 do begin DelimiterArray[i] := Delimiters[i+1]; end; case mode of dmUserFriendly: begin FWords := Split(Sentence, DelimiterArray, []); end; dmDelimiterExactly: begin FWords := Split(Sentence, DelimiterArray, [sfEmptyStr]); end; end; FSentence := Sentence; FDelimiters := Delimiters; end; destructor TWordDecompose.Destroy; begin inherited; end; function TWordDecompose.GetCount: Integer; begin Result := Length(FWords); end; function TWordDecompose.GetWords(Index: Integer): WideString; begin if ( 0 <= Index ) and ( Index <= (Length(FWords)-1) ) then begin Result := FWords[Index]; end else begin Result := ''; end; end; function TWordDecompose.IndexOf(const Word: String; IgnoreCase: Boolean): Integer; var i: Integer; CompareFunction: function(const S1, S2: string): Boolean; begin Result := -1; for i := 0 to Length(FWords)-1 do begin if (IgnoreCase=True) then begin CompareFunction := AnsiSameText; end else begin CompareFunction := AnsiSameStr; end; if CompareFunction(FWords[i], Word) then begin Result := i; Exit; end; end; end; {------------------------------- // 文字列を区切り文字で分解して 文字列動的配列として戻す関数 引数説明: WideStr:区切らせたい文字列 Delimiter:区切り文字の動的配列 ItemAddDelimiter:戻す配列内に区切り文字も含めるかどうかのフラグ ItemAddEmptyStr:戻す配列内に空文字列も入れるかどうかのフラグ 戻り値: WideStringの動的配列 備考: C#にあるのでDelphiでも実装してみた 部分文字列比較にWideStringPartsCompare関数を使っている 履歴: 2002/09/27 作成 2002/10/02 ItemAddDelimiterフラグを追加 2002/11/07 ItemAddEmptyStrフラグを追加 //------------------------------} (*----------------------------------- function Split(const WideStr: WideString; const Delimiter: TWideStringDynArray; Flags: TSplitFlags): TWideStringDynArray; { ----------------------------------- TWideStringDynArrayのIndexOf ただし、WideStrのIndexから始まる部分の文字列との一致を比較する //----------------------------------- } function WideStrArrayIndexOf(const WideStr: WideString; Index: Integer; StrArray: TWideStringDynArray): Integer; var i: Integer; begin Result := -1; for i := 0 to Length(StrArray)-1 do begin if WideStringPartsCompare(StrArray[i], WideStr, Index) then begin Result := i; exit; end; end; end; //WideStrArrayのAdd procedure WideStrArrayAdd(var WideStrArray: TWideStringDynArray; AddStr: WideString); begin SetLength(WideStrArray, Length(WideStrArray)+1); WideStrArray[Length(WideStrArray)-1] := AddStr; end; var i, j, ArrayIndex: Integer; Buffer: WideString; BufferLen: Cardinal; begin SetLength(Result, 0); BufferLen := 0; SetLength(Buffer, Length(WideStr)); i := 1; while i <= Length(WideStr) do begin ArrayIndex := WideStrArrayIndexOf(WideStr, i, Delimiter); {↓WideStrのi番目の文字がデリミタじゃない場合} if ArrayIndex = -1 then begin Inc(BufferLen); Buffer[BufferLen] := WideStr[i]; Inc(i); end else {↓WideStrのi番目の文字がデリミタの場合} begin if (1 <= BufferLen) or (sfEmptyStr in Flags) then begin SetLength(Buffer, BufferLen); WideStrArrayAdd(Result, Buffer); BufferLen := 0; SetLength(Buffer, Length(WideStr)); end; if sfDelimiter in Flags then begin for j := 1 to Length(Delimiter[ArrayIndex]) do begin Inc(BufferLen); Buffer[BufferLen] := Delimiter[ArrayIndex][j]; end; if (1 <= BufferLen) then begin SetLength(Buffer, BufferLen); WideStrArrayAdd(Result, Buffer); BufferLen := 0; SetLength(Buffer, Length(WideStr)); end; end; Inc(i, Length(Delimiter[ArrayIndex])); end; end; if (1<=BufferLen) or (sfEmptyStr in Flags) then begin SetLength(Buffer, BufferLen); WideStrArrayAdd(Result, Buffer); end; end; //-----------------------------------*) type TItemAddEvent = procedure(const AddStr: WideString); TSpliter = class(TObject) private procedure ItemAdd(const AddStr: WideString); virtual; abstract; public procedure Split(const WideStr: WideString; const Delimiter: TWideStringDynArray; Flags: TSplitFlags); end; TSpliterDynArray = class(TSpliter) private FResult: TWideStringDynArray; procedure ItemAdd(const AddStr: WideString); override; public constructor Create(Result: TWideStringDynArray); property Result: TWideStringDynArray read FResult; end; { TSpliterDynArray } constructor TSpliterDynArray.Create(Result: TWideStringDynArray); begin FResult := Result; end; procedure TSpliterDynArray.ItemAdd(const AddStr: WideString); begin SetLength(FResult, Length(FResult)+1); FResult[Length(FResult)-1] := AddStr; end; procedure TSpliter.Split(const WideStr: WideString; const Delimiter: TWideStringDynArray; Flags: TSplitFlags); { ----------------------------------- TWideStringDynArrayのIndexOf ただし、WideStrのIndexから始まる部分の文字列との一致を比較する //----------------------------------- } function WideStrArrayIndexOf(const WideStr: WideString; Index: Integer; StrArray: TWideStringDynArray): Integer; var i: Integer; begin Result := -1; for i := 0 to Length(StrArray)-1 do begin if WideStringPartsCompare(StrArray[i], WideStr, Index) then begin Result := i; exit; end; end; end; var i, j, ArrayIndex: Integer; Buffer: WideString; BufferLen: Cardinal; begin // SetLength(Result, 0); BufferLen := 0; SetLength(Buffer, Length(WideStr)); i := 1; while i <= Length(WideStr) do begin ArrayIndex := WideStrArrayIndexOf(WideStr, i, Delimiter); {↓WideStrのi番目の文字がデリミタじゃない場合} if ArrayIndex = -1 then begin Inc(BufferLen); Buffer[BufferLen] := WideStr[i]; Inc(i); end else {↓WideStrのi番目の文字がデリミタの場合} begin if (1 <= BufferLen) or (sfEmptyStr in Flags) then begin SetLength(Buffer, BufferLen); ItemAdd(Buffer); BufferLen := 0; SetLength(Buffer, Length(WideStr)); end; if sfIncludeDelimiter in Flags then begin for j := 1 to Length(Delimiter[ArrayIndex]) do begin Inc(BufferLen); Buffer[BufferLen] := Delimiter[ArrayIndex][j]; end; if (1 <= BufferLen) then begin SetLength(Buffer, BufferLen); ItemAdd(Buffer); BufferLen := 0; SetLength(Buffer, Length(WideStr)); end; end; Inc(i, Length(Delimiter[ArrayIndex])); end; end; if (1<=BufferLen) or (sfEmptyStr in Flags) then begin SetLength(Buffer, BufferLen); ItemAdd(Buffer); end; end; (*----------------------------------- //WideStrArrayのAdd procedure WideStrArrayAdd(var WideStrArray: TWideStringDynArray; AddStr: WideString); begin SetLength(WideStrArray, Length(WideStrArray)+1); WideStrArray[Length(WideStrArray)-1] := AddStr; end; //-----------------------------------*) function Split(const WideStr: WideString; const Delimiter: TWideStringDynArray; Flags: TSplitFlags): TWideStringDynArray; var Spliter: TSpliterDynArray; begin SetLength(Result, 0); Spliter := TSpliterDynArray.Create(Result); try Spliter.Split(WideStr, Delimiter, Flags); Result := Spliter.Result; finally Spliter.Free; end; end; function Split(const WideStr: WideString; const Delimiters: WideString; Flags: TSplitFlags): TWideStringDynArray; var Spliter: TSpliterDynArray; Delimiter: TWideStringDynArray; i: Integer; begin SetLength(Result, 0); SetLength(Delimiter, Length(Delimiters)); for i := 1 to Length(Delimiters) do begin Delimiter[i] := Delimiters[i]; end; Spliter := TSpliterDynArray.Create(Result); try Spliter.Split(WideStr, Delimiter, Flags); Result := Spliter.Result; finally Spliter.Free; end; end; procedure testSplit; var WideStrArray, Delimiter: TWideStringDynArray; ExampleStr: WideString; i: Integer; begin ExampleStr := ''; WideStrArray := Split(ExampleStr, Delimiter, []); Check(0, Length(WideStrArray)); ExampleStr := 'ABC DEF GHI'; SetLength(Delimiter, 1); Delimiter[0] := ''; WideStrArray := Split(ExampleStr, Delimiter, []); Check(1, Length(WideStrArray)); Check('ABC DEF GHI', WideStrArray[0]); ExampleStr := 'ABC DEF GHI'; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, []); Check(3, Length(WideStrArray)); Check('ABC', WideStrArray[0]); Check('DEF', WideStrArray[1]); Check('GHI', WideStrArray[2]); ExampleStr := ' ABC DEF GHI '; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, []); Check(3, Length(WideStrArray)); Check('ABC', WideStrArray[0]); Check('DEF', WideStrArray[1]); Check('GHI', WideStrArray[2]); ExampleStr := '- ABC - DEF-GHI '; SetLength(Delimiter, 3); Delimiter[0] := '-'; Delimiter[1] := '-'; Delimiter[2] := ' '; WideStrArray := Split(ExampleStr, Delimiter, []); Check(3, Length(WideStrArray)); Check('ABC', WideStrArray[0]); Check('DEF', WideStrArray[1]); Check('GHI', WideStrArray[2]); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 5); Delimiter[0] := 'を'; Delimiter[1] := 'えお'; Delimiter[2] := 'けこ'; Delimiter[3] := 'せそ'; Delimiter[4] := 'ねの'; WideStrArray := Split(ExampleStr, Delimiter, []); Check(4, Length(WideStrArray)); Check('あいう', WideStrArray[0]); Check('かきく', WideStrArray[1]); Check('さしす', WideStrArray[2]); Check('なにぬ', WideStrArray[3]); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 6); Delimiter[0] := 'を'; Delimiter[1] := 'あい'; Delimiter[2] := 'か'; Delimiter[3] := 'こ'; Delimiter[4] := 'さ'; Delimiter[5] := 'なに'; WideStrArray := Split(ExampleStr, Delimiter, []); Check(4, Length(WideStrArray)); Check('うえお', WideStrArray[0]); Check('きくけ', WideStrArray[1]); Check('しすせそ', WideStrArray[2]); Check('ぬねの', WideStrArray[3]); ExampleStr := 'うらにわにはにわにわにはにわにわとりがいる'; SetLength(Delimiter, 1); Delimiter[0] := 'は'; WideStrArray := Split(ExampleStr, Delimiter, []); Check(3, Length(WideStrArray)); Check('うらにわに', WideStrArray[0]); Check('にわにわに', WideStrArray[1]); Check('にわにわとりがいる', WideStrArray[2]); //////////////////////////////////////////////////////////// //↓デリミタを含む場合の処理 ExampleStr := ''; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(0, Length(WideStrArray)); ExampleStr := 'ABC DEF GHI'; SetLength(Delimiter, 1); Delimiter[0] := ''; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(1, Length(WideStrArray)); Check('ABC DEF GHI', WideStrArray[0]); ExampleStr := 'ABC DEF GHI'; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(5, Length(WideStrArray)); Check('ABC', WideStrArray[0]); Check(' ', WideStrArray[1]); Check('DEF', WideStrArray[2]); Check(' ', WideStrArray[3]); Check('GHI', WideStrArray[4]); ExampleStr := ' ABC DEF GHI '; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(11, Length(WideStrArray)); Check(' ', WideStrArray[0]); Check(' ', WideStrArray[1]); Check('ABC', WideStrArray[2]); Check(' ', WideStrArray[3]); Check(' ', WideStrArray[4]); Check('DEF', WideStrArray[5]); Check(' ', WideStrArray[6]); Check(' ', WideStrArray[7]); Check('GHI', WideStrArray[8]); Check(' ', WideStrArray[9]); Check(' ', WideStrArray[10]); ExampleStr := '- ABC - DEF-GHI '; SetLength(Delimiter, 3); Delimiter[0] := '-'; Delimiter[1] := '-'; Delimiter[2] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(11, Length(WideStrArray)); Check('-', WideStrArray[0]); Check(' ', WideStrArray[1]); Check('ABC', WideStrArray[2]); Check(' ', WideStrArray[3]); Check('-', WideStrArray[4]); Check(' ', WideStrArray[5]); Check('DEF', WideStrArray[6]); Check('-', WideStrArray[7]); Check('GHI', WideStrArray[8]); Check(' ', WideStrArray[9]); Check(' ', WideStrArray[10]); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 5); Delimiter[0] := 'を'; Delimiter[1] := 'えお'; Delimiter[2] := 'けこ'; Delimiter[3] := 'せそ'; Delimiter[4] := 'ねの'; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(8, Length(WideStrArray)); Check('あいう', WideStrArray[0]); Check('えお', WideStrArray[1]); Check('かきく', WideStrArray[2]); Check('けこ', WideStrArray[3]); Check('さしす', WideStrArray[4]); Check('せそ', WideStrArray[5]); Check('なにぬ', WideStrArray[6]); Check('ねの', WideStrArray[7]); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 6); Delimiter[0] := 'を'; Delimiter[1] := 'あい'; Delimiter[2] := 'か'; Delimiter[3] := 'こ'; Delimiter[4] := 'さ'; Delimiter[5] := 'なに'; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(9, Length(WideStrArray)); Check('あい', WideStrArray[0]); Check('うえお', WideStrArray[1]); Check('か', WideStrArray[2]); Check('きくけ', WideStrArray[3]); Check('こ', WideStrArray[4]); Check('さ', WideStrArray[5]); Check('しすせそ', WideStrArray[6]); Check('なに', WideStrArray[7]); Check('ぬねの', WideStrArray[8]); ExampleStr := 'うらにわにはにわにわにはにわにわとりがいる'; SetLength(Delimiter, 1); Delimiter[0] := 'は'; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter]); Check(5, Length(WideStrArray)); Check('うらにわに', WideStrArray[0]); Check('は', WideStrArray[1]); Check('にわにわに', WideStrArray[2]); Check('は', WideStrArray[3]); Check('にわにわとりがいる', WideStrArray[4]); //////////////////////////////////////////////////////////// //↓ヌル文字を含む場合の処理 ExampleStr := ''; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'ABC DEF GHI'; SetLength(Delimiter, 1); Delimiter[0] := ''; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('ABC DEF GHI', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'ABC DEF GHI'; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('ABC', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('DEF', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('GHI', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := ' ABC DEF GHI '; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('ABC', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('DEF', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('GHI', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := ' ABC DEF GHI '; SetLength(Delimiter, 1); Delimiter[0] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('ABC', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('DEF', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('GHI', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := '- ABC - DEF-GHI '; SetLength(Delimiter, 3); Delimiter[0] := '-'; Delimiter[1] := '-'; Delimiter[2] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check('-', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('ABC', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('-', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('DEF', WideStrArray[i]); Inc(i); Check('-', WideStrArray[i]); Inc(i); Check('GHI', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(' ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := '- ABC - DEF-GHI '; SetLength(Delimiter, 3); Delimiter[0] := '-'; Delimiter[1] := '-'; Delimiter[2] := ' '; WideStrArray := Split(ExampleStr, Delimiter, [sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('ABC', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('DEF', WideStrArray[i]); Inc(i); Check('GHI', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 5); Delimiter[0] := 'を'; Delimiter[1] := 'えお'; Delimiter[2] := 'けこ'; Delimiter[3] := 'せそ'; Delimiter[4] := 'ねの'; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('あいう', WideStrArray[i]); Inc(i); Check('えお', WideStrArray[i]); Inc(i); Check('かきく', WideStrArray[i]); Inc(i); Check('けこ', WideStrArray[i]); Inc(i); Check('さしす', WideStrArray[i]); Inc(i); Check('せそ', WideStrArray[i]); Inc(i); Check('なにぬ', WideStrArray[i]); Inc(i); Check('ねの', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 5); Delimiter[0] := 'を'; Delimiter[1] := 'えお'; Delimiter[2] := 'けこ'; Delimiter[3] := 'せそ'; Delimiter[4] := 'ねの'; WideStrArray := Split(ExampleStr, Delimiter, [sfEmptyStr]); i := 0; Check('あいう', WideStrArray[i]); Inc(i); Check('かきく', WideStrArray[i]); Inc(i); Check('さしす', WideStrArray[i]); Inc(i); Check('なにぬ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 6); Delimiter[0] := 'を'; Delimiter[1] := 'あい'; Delimiter[2] := 'か'; Delimiter[3] := 'こ'; Delimiter[4] := 'さ'; Delimiter[5] := 'なに'; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check('あい', WideStrArray[i]); Inc(i); Check('うえお', WideStrArray[i]); Inc(i); Check('か', WideStrArray[i]); Inc(i); Check('きくけ', WideStrArray[i]); Inc(i); Check('こ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('さ', WideStrArray[i]); Inc(i); Check('しすせそ', WideStrArray[i]); Inc(i); Check('なに', WideStrArray[i]); Inc(i); Check('ぬねの', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'あいうえおかきくけこさしすせそなにぬねの'; SetLength(Delimiter, 6); Delimiter[0] := 'を'; Delimiter[1] := 'あい'; Delimiter[2] := 'か'; Delimiter[3] := 'こ'; Delimiter[4] := 'さ'; Delimiter[5] := 'なに'; WideStrArray := Split(ExampleStr, Delimiter, [sfEmptyStr]); i := 0; Check('', WideStrArray[i]); Inc(i); Check('うえお', WideStrArray[i]); Inc(i); Check('きくけ', WideStrArray[i]); Inc(i); Check('', WideStrArray[i]); Inc(i); Check('しすせそ', WideStrArray[i]); Inc(i); Check('ぬねの', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'うらにわにはにわにわにはにわにわとりがいる'; SetLength(Delimiter, 1); Delimiter[0] := 'は'; WideStrArray := Split(ExampleStr, Delimiter, [sfIncludeDelimiter, sfEmptyStr]); i := 0; Check('うらにわに', WideStrArray[i]); Inc(i); Check('は', WideStrArray[i]); Inc(i); Check('にわにわに', WideStrArray[i]); Inc(i); Check('は', WideStrArray[i]); Inc(i); Check('にわにわとりがいる', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); ExampleStr := 'うらにわにはにわにわにはにわにわとりがいる'; SetLength(Delimiter, 1); Delimiter[0] := 'は'; WideStrArray := Split(ExampleStr, Delimiter, [sfEmptyStr]); i := 0; Check('うらにわに', WideStrArray[i]); Inc(i); Check('にわにわに', WideStrArray[i]); Inc(i); Check('にわにわとりがいる', WideStrArray[i]); Inc(i); Check(i, Length(WideStrArray)); end; //------------------------------ end.