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?

