Does Delphi (10.4) have a string-tokenizer that extracts string-token-objects from a string in a similar way as below?
MyPhrase := 'I have a simple word and a complex Word: A lot of WORDS.';
MyTokens := MyTokenize(MyPhrase, 'word');
for i := 0 to MyTokens.Count - 1 do
Memo1.Lines.Add(IntToStr(MyTokens[i].Pos) + ': ' + MyTokens[i].String);
Gives this result in Memo1:
16: word
35: Word
50: WORD
Searching for "tokenize string" in the Delphi documentation did not get any useful results for this purpose.
Of course, writing such a function is trivial, but I wonder if there already is a procedure for this in the existing huge Delphi code treasure.
EDIT: I am experimenting with a wordlist that should have the required features:
program MyTokenize;
{$APPTYPE CONSOLE}
{$R *.res}
uses
CodeSiteLogging,
System.RegularExpressions,
System.Types,
System.Classes,
System.StrUtils,
System.SysUtils;
type
PWordRec = ^TWordRec;
TWordRec = record
WordStr: string;
WordPos: Integer;
end;
TWordList = class(TList)
private
function Get(Index: Integer): PWordRec;
public
destructor Destroy; override;
function Add(Value: PWordRec): Integer;
property Items[Index: Integer]: PWordRec read Get; default;
end;
function TWordList.Add(Value: PWordRec): Integer;
begin
Result := inherited Add(Value);
end;
destructor TWordList.Destroy;
var
i: Integer;
begin
for i := 0 to Count - 1 do
FreeMem(Items[i]);
inherited;
end;
function TWordList.Get(Index: Integer): PWordRec;
begin
Result := PWordRec(inherited Get(Index));
end;
var
WordList: TWordList;
WordRec: PWordRec;
i: Integer;
begin
try
//MyPhrase := 'A crossword contains words but not WORD';
WordList := TWordList.Create;
try
// AV only at the THIRD loop!!!
for i := 0 to 2 do
begin
GetMem(WordRec, SizeOf(TWordRec));
WordRec.WordPos := i;
WordRec.WordStr := IntToStr(i);
WordList.Add(WordRec);
end;
for i := 0 to WordList.Count - 1 do
Writeln('WordPos: ', WordList[i].WordPos, ' WordStr: ', WordList[i].WordStr);
WriteLn(' Press Enter to free the list');
ReadLn;
finally
WordList.Free;
end;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
ReadLn;
end;
end;
end.
Unfortunately, it has a strange bug: It gets an AV exactly at the THIRD for loop!
EDIT2: It seems that the AV happens only when the project's Build Configuration is set to Debug
. When the project's Build Configuration is set to Release
then there is no AV. Has this to do with the MemoryManager?