2015-06-14 85 views
2

我想寫一個函數來提取兩個標籤之間的字符串。 問題是第一個標記在該字符串中是重複的,並且計數未知德爾福 - 提取標籤之間的字符串(重複標籤)

Str := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!'; 

我要的究竟是提取你好這是一個測試!

  • TagF是最後你好
  • TAGL是測試!

TagF它的隨機重複計數。

Function sExtractBetweenTagsB(Const s, LastTag, FirstTag: string): string; 
var 
    i, f : integer; 
    sTemp : string; 
begin 
    sTemp := s; 
    repeat 
    Delete(sTemp,Pos(FirstTag, sTemp),length(FirstTag)); 
    until AnsiPos(FirstTag,sTemp) = 0; 
    f := Pos(LastTag, sTemp); 
    Result:= FirstTag+' '+Copy(sTemp, 1, length(sTemp)); 
end; 

輸出是:

Hello Delphi App SomeText here This is a Test! 
+1

嘗試'LastDelimiter'功能 – MBo

+1

@Mbo:雖然方便,我寧願用'PosEx'停留在32位,因爲它具有同時'LastDelimiter一個Fastcode優化'沒有。 – whosrdaddy

回答

2
Function sExtractBetweenTagsB(Const s, LastTag, FirstTag: string): string; 
var 
    pLast,pFirst,pNextFirst : Integer; 
begin 
    pFirst := Pos(FirstTag,s); 
    pLast := Pos(LastTag,s); 
    while (pLast > 0) and (pFirst > 0) do begin 
    if (pFirst > pLast) then // Find next LastTag 
     pLast := PosEx(LastTag,s,pLast+Length(LastTag)) 
    else 
    begin 
     pNextFirst := PosEx(FirstTag,s,pFirst+Length(FirstTag)); 
     if (pNextFirst = 0) or (pNextFirst > pLast) then begin 
     Result := Copy(s,pFirst,pLast-pFirst+Length(LastTag)); 
     Exit; 
     end 
     else 
     pFirst := pNextFirst; 
    end; 
    end; 
    Result := ''; 
end; 

var 
    s: String; 

begin 
    s := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test! Hello'; 
    WriteLn(sExtractBetweenTagsB(s,'Test','Hello')); 
end. 

輸出:

Hello This is a Test 
+0

只是其輝煌 – RepeatUntil

4

可以使用PosEx功能來掃描您的字符串標記,然後向前搜索:

Input: "Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!" 
Ouput: "Hello This is a Test!" 
Input: " Test! Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test! Some end chars" 
Ouput: "Hello This is a Test!" 

program SO30827180; 

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    SysUtils, 
    StrUtils; 

function ExtractString(const Input : String; const TagF: String; const TagL : String) : String; 

var 
    LastPos : Integer; 
    NewPos : Integer; 

begin 
Result := ''; 
NewPos := Pos(TagF, Input); 
if NewPos <> 0 then 
    begin 
    LastPos := NewPos; 
    // scan to last start tag 
    while true do 
    begin 
    NewPos := PosEx(TagF, Input, NewPos+1); 
    if NewPos <> 0 then 
     LastPos := NewPos 
    else 
     Break; 
    end; 
    // now seek end tag, starting from last starting tag position 
    NewPos := PosEx(TagL, Input, LastPos+1); 
    if NewPos <> 0 then 
    Result := Copy(Input, LastPos, NewPos-LastPos+Length(TagL)); 
    end; 
end; 

var 
    Line : String; 

begin 
Line := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!'; 
Writeln(Format('Input: "%s"', [Line])); 
Writeln(Format('Ouput: "%s"', [ExtractString(Line, 'Hello', 'Test!')])); 
Line := ' Test! Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test! Some end chars'; 
Writeln(Format('Input: "%s"', [Line])); 
Writeln(Format('Ouput: "%s"', [ExtractString(Line, 'Hello', 'Test!')])); 
Readln; 
end. 

從示例輸出

+0

如果最後一個標籤後面有第一個標籤,則不起作用。 –

+2

@LURD那麼需求並不那麼清楚,是嗎?如果我正確理解OP,提取將從最後一個開始標記處開始。如果之後沒有結束標籤,那麼結果應該是空的,而不是? – whosrdaddy

+1

@whosrdaddy這就是我要求的感謝。 – RepeatUntil

2

要做到這一點,最簡單的方法是使用正則表達式:?!

program Project1; 

{$APPTYPE CONSOLE} 

uses 
    RegularExpressions; 

var 
    regEx : TRegEx; 
    testString : string; 
    m : TMatch; 
begin 
    testString := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!'; 

    regEx := TRegEx.Create('(Hello(?!.*Hello).*?Test!)'); 
    m := regEx.Match(testString); 

    if m.Success then 
    WriteLn(m.Value) 
    else 
    WriteLn('No match.'); 
    ReadLn; 
end. 

這裏正則表達式是

  • (你好(*你好)
    - 匹配「Hello」和str中後面沒有「Hello」的實例ing(貪婪lookahead)
  • 。*?
    - 懶匹配任何
  • 測試)
    ! - 匹配 「測試!」

如果要概括:

function ExtractBetweenTags(const s : string; FirstTag, LastTag : string) : string; 
var 
    regEx : TRegEx; 
begin 
    regEx := TRegEx.Create(Format('(%s(?!.*%s).*?%s)', [FirstTag, FirstTag, LastTag])); 
    result := regEx.Match(s).Value; 
end; 
相關問題