Delphi 将其他两个字符串之间的所有字符串实例写入日志文件
在查看并尝试Andreas Rejbrand给出的代码后,我意识到我需要一个不会在一个标记后停止的版本—我的目标是将几个.xml文件中两个字符串之间出现的所有值写入日志文件Delphi 将其他两个字符串之间的所有字符串实例写入日志文件,delphi,delphi-10-seattle,Delphi,Delphi 10 Seattle,在查看并尝试Andreas Rejbrand给出的代码后,我意识到我需要一个不会在一个标记后停止的版本—我的目标是将几个.xml文件中两个字符串之间出现的所有值写入日志文件 <screen> xyz </screen> blah blah <screen> abc </screen> procedure TTagtextextract0r.FormCreate(Sender: TObject); begin Edit2.Text:=(TDi
<screen> xyz </screen> blah blah <screen> abc </screen>
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.
我的问题是,如果函数中没有布尔循环,应用程序只会在每个文件中写入一行,然后停止,但是使用布尔代码,应用程序会陷入无限循环中——但我不太清楚循环没有结束的地方。是不是“WriteLn”命令无法输出函数的结果?如果不能,我不知道如何为函数的每次运行获得一个新行-我在这里做错了什么 首先,您需要掌握调试 请参阅,了解如何暂停和调试失控的程序 另请阅读以了解如何使用断点。如果你已经仔细检查了你的代码,你很快就会发现你错在哪里了 那么你的问题是: 在旧的Delphi版本(直到Delphi XE2)中,您可以使用
PosEx()
函数(如注释中所建议的),这将大大简化ExtractText()
函数中的代码。从Delphi XE3中,扩展了System.Pos()
函数,其功能与PosEx()
相同,即第三个参数Offset:integer
由于您使用的是Delphi 10西雅图版,因此可以互换使用System.StrUtils.PosEx()
或System.Pos()
System.StrUtils.PosEx
PosEx()返回以S为单位的SubStr索引,从开始搜索
抵消
ExtractText()
函数ExtractText(const标记,text:string):string;
变量
startPos,endPos:整数;
开始
结果:='';
startPos:=1;
重复
startPos:=PosEx(“”,text,startPos)+1;
如果startPos=1,则退出;
endPos:=PosEx(“”,text,startPos);
如果endPos=0,则退出;
结果:=结果+复制(文本、起始位置、结束位置-起始位置)+sLineBreak;
直到错误;
结束;
我在每个找到的文本后添加了sLineBreak
(在unitSystem.Types
),否则它应该按照您的预期工作(我相信)。学习1)正确缩进代码,以便您可以看到块的开始和停止位置,以及2)学习使用调试器逐步检查代码以查看发生了什么。在本例中,在ListBox2.Items.Add(Files[k])处设置断点
并使用F8逐步执行代码以执行每一行。(还有一个提示:将AssignFile
移动到循环开始之前,将CloseFile
移动到循环结束之后。在循环的每次迭代中重复打开和关闭它是没有意义的。)请注意,您可以使用PosEx
功能从最后一个位置继续搜索,因此,避免使用delete
用法。使用xml语法你没有删除文本读取的部分-你正在删除第一个“嗨,伙计们,谢谢你们的支持。”。是的,我现在看到缩进的好处了!(@LU RD感谢您的编辑)我尝试了断点,然后可以将鼠标悬停在变量上,查看分配给它们的值,非常有用。我接受你关于循环中的开始和结束的观点,KW,谢谢。是的,感谢DH,XML解析器是我没有考虑过的一种方法,我必须仔细阅读它!啊,是的,现在也发现了无限循环,谢谢Dsm!谢谢你关于PosEx MBo的留言!在较新的Delphi版本(Unicode)中,相当于System.StrUtils.PosEx()
@LURD-holy!看来是这样。谢谢,我不知道。我需要重新措辞我的帖子。@LURD我的安装有漏洞。D2010 Pos()无法识别第三个参数。DXE4有。您是否安装了XE、XE2或XE3中的任何一个以检查何时发生更改?从中,似乎XE3是第一个引入偏移量的。我手头没有XE2来检查代码。我今天晚些时候再看。它是XE3的,检查过了。
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.
function PosEx(const SubStr, S: string; Offset: Integer = 1): Integer; inline; overload;
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;