在查看Delphi extract string between to 2 tags并尝试Andreas Rejbrand给出的代码后,我意识到我需要一个不会在一个标签之后停止的版本 - 我的目标是写出两个字符串之间出现的所有值几个.xml文件到日志文件。
function ExtractText(const Tag, Text: string): string;
var
StartPos1, StartPos2, EndPos: integer;
i: Integer;
mytext : string;
bFinished : bool;
begin
bFinished := false;
mytext := text;
result := '';
while not bFinished do
begin
StartPos1 := Pos('<' + Tag, mytext);
if StartPos1 = 0 then bFinished := true;
EndPos := Pos('</' + Tag + '>', mytext);
StartPos2 := 0;
for i := StartPos1 + length(Tag) + 1 to EndPos do
if mytext[i] = '>' then
begin
StartPos2 := i + 1;
break;
end;
if (StartPos2 > 0) and (EndPos > StartPos2) then
begin
result := result + Copy(mytext, StartPos2, EndPos - StartPos2);
delete (mytext, StartPos1, 1);
end
- &GT;给出一个日志文件
xyz
abc
......等等。
我尝试删除函数读取的部分文本,这样当函数重复时,它将转到所需字符串的下一个实例,然后将其写入日志文件,直到没有匹配为止left - 布尔函数为true,函数可以停止 - 在略微修改的函数下面,基于链接中的版本。
procedure TTagtextextract0r.FormCreate(Sender: TObject);
begin
Edit2.Text:=(TDirectory.GetCurrentDirectory);
AssignFile(LogFile, 'Wordlist.txt');
ReWrite(LogFile);
CloseFile(Logfile);
end;
所以我创建了表单并分配了一个日志文件。
procedure TTagtextextract0r.Button3Click(Sender: TObject);
begin
try
sD := TDirectory.GetCurrentDirectory;
Files:= TDirectory.GetFiles(sD, '*.xml');
except
exit
end;
j:=Length(Files);
for k := 0 to j-1 do
begin
Listbox2.Items.Add(Files[k]);
sA:= TFile.ReadAllText(Files[k]);
iL:= Length(sA);
AssignFile(LogFile, 'Wordlist.txt');
Append(LogFile);
WriteLn(LogFile, (ExtractText('screen', sA)));
CloseFile (LogFile);
end;
end;
end.
然后要获取有问题的文件,我点击一个按钮然后读取它们。
{{1}}
我的问题是,如果没有函数中的布尔循环,应用程序只会为每个文件写入一行,然后停止但是使用布尔代码将应用程序卡在无限循环中 - 但我无法看到循环没有结束。或许“WriteLn”命令无法输出函数的结果吗?如果它不能,我不知道如何为每个功能运行获得一个新行 - 我在这里做错了什么?
答案 0 :(得分:1)
首先,您需要掌握调试
查看this post,了解如何暂停和调试狂野的程序。
另请阅读Setting and modifying breakpoints以了解如何使用断点。如果你已经完成了代码,你很快就会看到你出错的地方。
然后问题:
在较旧的Delphi版本(直到Delphi XE2)中,您可以使用PosEx()
函数(如注释中所示),这将显着简化ExtractText()
函数中的代码。从Delphi XE3开始,System.Pos()
函数已扩展,其功能与PosEx()
相同,即第三个参数Offset: integer
由于您使用的是Delphi 10 Seattle,您可以互换使用System.StrUtils.PosEx()
或System.Pos()
。
System.StrUtils.PosEx
PosEx()返回S中的SubStr索引,开始搜索 偏移
function PosEx(const SubStr, S: string; Offset: Integer = 1): Integer; inline; overload;
ExtractText()
的实现可能如此(使用PosEx()
):
function ExtractText(const tag, text: string): string;
var
startPos, endPos: integer;
begin
result := '';
startPos := 1;
repeat
startPos := PosEx('<'+tag, text, startpos);
if startPos = 0 then exit;
startPos := PosEx('>', text, startPos)+1;
if startPos = 1 then exit;
endPos := PosEx('</'+tag+'>', text, startPos);
if endPos = 0 then exit;
result := result + Copy(text, startPos, endPos - startPos) + sLineBreak;
until false;
end;
我在每个找到的文字后添加了sLineBreak
(在单位System.Types
中),否则它应该按照您的预期工作(我相信)。