2016-10-22 74 views
1

我需要提取一個特定的分隔符後的子字符串,但如果指定的分隔符是兩個其他標籤之間,它應該被忽略。如何在分隔符之後提取子字符串,但忽略在兩個標籤之間找到?

例如,藉此測試字符串:

快速< 「@brown狐狸」>躍過懶狗。快速@的棕色狐狸 躍過懶狗

所需的輸出將是:

的棕色狐狸跳過懶狗

這是因爲首先發現@分隔符是在兩個「」之間,所以應該被忽略,第二個@分隔符不在「」之內,因此後面的文本應該被提取。

我能夠通過使用Pos和提取文本到它的右邊找到了@頭的起始位置如下圖所示:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    S: string; 
    I: Integer; 
begin 
    S := 'The quick <"@brown fox"> jumps over the lazy dog. The quick @brown fox jumps over the lazy dog'; 
    I := Pos('@', S); 
    if I > 0 then 
    begin 
    ShowMessage(Copy(S, I, Length(S))); 
    end; 
end; 

然而,這總是會找到第一個@符不管它被兩個「」包圍或不包圍。從以上的結果是:

@brown狐「>跳通過惰性狗@棕色狐狸過 跳躍惰性狗

其中所希望的結果應該是快速。:

的棕色狐狸跳過懶狗

如果分隔符介於兩個「」標籤之間,那麼在使用Pos時,如何更改代碼以忽略@分隔符?我只想找到第一個@分隔符,然後複製文本。

它還如果有後的第一個有效的任何其它@分隔符被發現,例如這也應該是有效不要緊:

快速<「@brown狐狸」>躍過懶狗。快速@的棕色狐狸 跳@ OV @ ER懶惰@狗

還是應該返回:

的棕色狐狸跳過懶狗

因爲我們只對第一個有效的@分隔符感興趣,忽略其他任何事情,忽略兩個「」標籤之間的任何內容。

請注意,儘管我已標記的德爾福我主要使用拉撒路所以最好我需要幫助,想出不使用魔法的幫助用繩子助手等

感謝的解決方案。

回答

1

要了解的@不在範圍"封閉標籤,解析從一開始的字符串。

如果在開始標記後發現分隔符,但沒有結束標記,則此例程也將提取結果。

function ExtractString(const s: String): String; 
var 
    tagOpen: Boolean; 
    delimiterPos,i,j: Integer; 
begin 
    tagOpen := false; 
    delimiterPos := 0; 
    Result := ''; 
    for i := 1 to Length(s) do begin 
    if (s[i] = '"') then begin 
     tagOpen := not tagOpen; 
     delimiterPos := 0; 
    end 
    else begin 
     if (s[i] = '@') then begin 
     if (delimiterPos = 0) then 
      delimiterPos := i; 
     if not tagOpen then // Found answer 
      Break; 
     end; 
    end;   
    end; 

    // If there is no closing tag and a delimiter is found 
    // since the last opening tag, deliver a result. 
    if (delimiterPos > 0) then begin 
    // Finally extract the string and remove all `@` delimiters. 
    SetLength(Result,Length(s)-delimiterPos); 
    j := 0; 
    for i := 1 to Length(Result) do begin 
     Inc(delimiterPos); 
     if (s[delimiterPos] <> '@') then begin 
     Inc(j); 
     Result[j] := s[delimiterPos]; 
     end; 
    end; 
    SetLength(Result,j);  
    end; 
end; 
+0

輝煌,並感謝在評論中加入太多:) – Craig

0
procedure TForm1.Button1Click(Sender: TObject); 
var 
    S: string; 
    L, I: Integer; 
    take : Boolean; 
begin 
    S := 'The quick <"@brown fox"> jumps over the lazy dog. The quick @brown fox jumps over the lazy dog'; 
    L := Length(S); 
    I := Pos('@', S); 

    while I > 0 do 
    begin 
    take := True; 
    if I > 1 then take := S[I-1] <> '"'; 
    if take then begin 
     if I < L then 
     ShowMessage(Copy(S, I + 1, L)); 
     Break; 
    end; 
    S[I] := '_'; 
    I := Pos('@', S); 
    end; 
end; 
+1

如果'「'打開標籤不止一個位置之前'@',或者是結束標記不工作。 –

相關問題