2016-11-15 2 views
-1

Delphi extract string between to 2 tagsを見て、Andreas Rejbrandが与えたコードを試してみたら、1つのタグの後で止まらないバージョンが必要だった。いくつかの.xmlファイル内の2つの文字列の間に発生する値をログファイルに書き込みます。2つの他の文字列の間のすべてのインスタンスをログファイルに書き込む

<screen> xyz </screen> blah blah <screen> abc </screen> 

- >ように
XYZ
ABC
...としてログファイルを与えます。

私が試みたのは、関数が読み込んだテキストの一部を削除して、関数が繰り返されると、目的の文字列の次のインスタンスに移動し、それがログファイルに書き込まれるまでリンクのバージョンに基づいてわずかに変更された関数の下で真となり、関数は停止する可能性があります。

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 

私はフォームを作成し、ログファイルを割り当てます。

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. 

私の問題は、関数のbooleanループせずに、アプリケーションは専用のファイルごとに1行を書き込み、その後、アプリケーションが無限ループで立ち往生ブールのコードではなく停止することである - しかし、私はできませんループがどこで終わらないのかがよく分かります。おそらく "WriteLn"コマンドがその関数の結果を出力できないのでしょうか?それができない場合は、関数を実行するたびに新しい行を取得する方法がわかりません。ここで間違っていますか?

+1

ブロックを開始および停止する場所を確認できるようにコードを適切にインデントする方法と、2)デバッガを使用してコードをステップ実行して何が起こっているのかを確認する方法を学びます。この場合、 'ListBox2.Items.Add(Files [k]);'にブレークポイントを設定し、F8キーを使用して各行を実行します。 (そしてヒント: 'AssignFile'をループ開始の前に、' CloseFile'をループ終了の後に移動してください。ループの各繰り返しでそれを繰り返し開いたり閉じたりする必要はありません。 –

+0

' PosEx'関数は最後の位置からの検索を続けるため、 'delete'の使用を避けます。 – MBo

+2

xmlパーサーを使用 –

答えて

1

まず、暴走プログラムを一時停止し、デバッグする方法についての説明会のためにthis post

ルックをデバッグする上でのグリップを取得する必要があります。

また、Setting and modifying breakpointsを読み、ブレークポイントの使い方を学んでください。あなたのコードを踏んできたのであれば、どこが間違っているのかはすぐに分かりました。あなたの問題に続いて

:あなたはかなりExtractText()機能でコードを単純化するPosEx()機能を(コメントで示唆したように)、使用することができます(デルファイXE2まで)古いDelphiのバージョンでは

。デルファイXE3からSystem.Pos()機能がPosEx()と同じ機能で拡張されました、それは、三番目のパラメータであるOffset: integer

あなたがデルファイ10、シアトルにあるので、あなたは、交換可能にSystem.StrUtils.PosEx()またはSystem.Pos()のいずれかを使用することができます。

System.StrUtils。POSEX

POSEX() で検索を始め、SにSUBSTRのインデックスを返しますExtractText()の実装は(PosEx()で)このようになります。

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; 

私はそれぞれの見つかったテキストの後にsLineBreak(ユニットSystem.Types)を追加しました。そうでなければ、意図したとおりに動作するはずです(私は信じています)。

+0

新しいDelphiのバージョン(Unicode)では、[System.Pos()](http://docwiki.embarcadero.com/Libraries/en/System.Pos)は 'System.StrUtils.PosEx()'に相当します。 –

+1

@LURD聖なる...!そうらしい、それっぽい。ありがとう、私はそれを知らなかった。私は私のポストを言い換える必要があります。 –

+0

@LURD私のインストールにはギャップがあります。 D2010 Pos()は3番目のパラメータを認識しません。 DXE4はそうです。 XE、XE2、XE3のいずれかがインストールされていますか? –

関連する問題