将两个其他字符串之间的所有字符串实例写入logfile

时间:2016-11-15 00:10:07

标签: delphi delphi-10-seattle

在查看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”命令无法输出函数的结果吗?如果它不能,我不知道如何为每个功能运行获得一个新行 - 我在这里做错了什么?

1 个答案:

答案 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中),否则它应该按照您的预期工作(我相信)。