2016-11-15 5 views
-1

Delphi extract string between to 2 tags을보고 Andreas Rejbrand가 제공 한 코드를 시도한 후에 하나의 태그 뒤에 멈추지 않는 버전이 필요하다는 것을 깨달았습니다. 여러 .xml 파일의 두 문자열 사이에서 발생하는 값을 로그 파일에 저장합니다.다른 두 문자열 사이에 문자열의 모든 인스턴스를 로그 파일로 작성

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

-> 등등
XYZ
ABC
... 그리고있는 로그 파일을 제공합니다.

필자가 시도한 것은 함수에서 읽은 텍스트의 일부를 삭제하여 함수가 반복 될 때 원하는 문자열의 다음 인스턴스로 이동 한 다음 로그 파일에 그 문자열이 없을 때까지 기록하는 것이 었습니다 왼쪽 일치 - 부울 함수가 true이고 함수가 중지 될 수 있음 - 링크의 버전을 기반으로 약간 수정 된 함수 아래

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. 

내 문제는 함수에서 부울 루프없이, 응용 프로그램은 파일 당 한 줄을 작성하고 응용 프로그램이 무한 루프에 걸리면 부울 코드를 중지 한 것입니다 -하지만 그럴 수 없어 루프가 끝나지 않는 곳을 확실히보십시오. 아마도 "WriteLn"명령이 함수의 결과를 출력 할 수 없습니까? 그렇지 못하다면 함수를 실행할 때마다 새로운 라인을 얻는 방법을 모르겠다. 여기서 내가 뭘 잘못하고 있니?

+1

1) 블록을 시작하고 멈출 곳을 볼 수 있도록 코드를 들여 쓰기하고 2) 디버거를 사용하여 코드를 단계별로 실행하여 무슨 일이 일어나는지 확인하는 방법을 배웁니다. 이 경우'ListBox2.Items.Add (Files [k]);'에 중단 점을 설정하고 F8 키를 사용하여 각 행을 실행하십시오. (그리고 힌트 :'AssignFile'을 루프 시작 전에 움직이고'CloseFile'을 루프 끝단 다음으로 이동하십시오. 루프의 반복마다 반복해서 열고 닫을 필요가 없습니다.) –

+0

' PosEx' 함수는 마지막 위치에서 검색을 계속하기 때문에'delete' 사용법을 피하십시오. – MBo

+2

xml 파서 사용 –

답변

1

먼저 일시 중지하는 방법에 대한 브리핑 this post에서

봐 디버깅 및 야생 사라 프로그램을 디버깅에 그립을 얻을 필요가있다.

또한 Setting and modifying breakpoints을 읽고 중단 점을 사용하는 방법을 배우십시오. 코드를 살펴 보았 더라면 곧 어디서 잘못되었는지 보았을 것입니다.

는 그런 문제에 : (델파이 XE2까지) 이전 델파이 버전의

당신은 크게 ExtractText() 기능의 코드를 단순화하는 것이다 (같은 의견 제안)을 PosEx() 기능을 사용할 수 있습니다. 델파이 XE3에서 System.Pos() 기능이 PosEx()와 동일한 기능, 세 번째 매개 변수 Offset: integer

로 확장 된 델파이 10 시애틀에 있기 때문에 당신이 상호 교환하거나 System.StrUtils.PosEx() 또는 System.Pos()를 사용할 수 있습니다.

System.StrUtils.PosEx

PosEx는() 에서 검색

function PosEx(const SubStr, S: string; Offset: Integer = 1): Integer; inline; overload; 

ExtractText()의 구현은 (PosEx()와) 같이 할 수

오프셋 시작, S에서 SUBSTR의 인덱스를 반환

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

최신 델파이 (유니 코드) 버전에서는 [System.Pos()] (http://docwiki.embarcadero.com/Libraries/en/System.Pos)는'System.StrUtils.PosEx()'와 동일합니다. –

+1

@LURD 거룩한 ...! 그렇게 보인다. 고마워, 나는 그것을 몰랐다. 내 글을 다시 말해야 해. –

+0

@LURD 설치 과정에 차이가 있습니다. D2010 Pos()가 세 번째 매개 변수를 인식하지 못합니다. DXE4 않습니다. 변경된시기를 확인하기 위해 XE, XE2 또는 XE3을 설치 했습니까? –