2016-10-03 163 views
2

我想在Delphi XE7中使用TRegex來執行搜索並替換字符串。如何使用Delphi TRegEx替換特定的捕獲組?

的字符串看起來像 「@FXXX(B,V,」 我想更換第二個整數值v 例如: @ F037(594,2027,-99,-99,0,0 ,0,0)

可能成爲 @ F037(594,弗雷德,-99,-99,0,0,0,0)

我在正則表達式的一個新手,但由這種模式似乎爲了找到匹配併爲「2027」確定正確的捕獲組(在括號中的部分),它是:

@F \ d {3}(\ s * \ d {1, 5} \ S *,\ S *(\ d {1,5})\ S *,

我的問題是,我不能解決如何使用Delphi TRegEx實現替換捕獲的組「2027」。我對TMatch和TGroup以及如何使用它們感到困惑。任何人都可以提供一些示例代碼?我也懷疑我不理解反向引用的概念。

這是我到目前爲止有:

Uses 
    RegularExpressions; 

//The function that does the actual replacement 
function TForm6.DoReplace(const Match: TMatch): string; 
begin 
    //This causes the whole match to be replaced. 
    //@F037(594,2027,-99,-99,0,0,0,0) becomes Fred-99,-99,0,0,0,0) 
    //How to just replace the first matched group (ie 2027)? 
    If Match.Success then 
    Result := 'Fred'; 
end; 


//Code to set off the regex replacement based on source text in Edit1 and put the result back into Memo1 
//Edit1.text set to @F037(594,2027,-99,-99,0,0,0,0) 

procedure TForm6.Button1Click(Sender: TObject); 

var 
    regex: TRegEx; 
    Pattern: string; 
    Evaluator: TMatchEvaluator; 

begin 
    Memo1.Clear; 
    Pattern := '@F\d{3}\(\s*\d{1,5}\s*,\s*(\d{1,5})\s*,'; 
    RegEx.Create(Pattern); 
    Evaluator := DoReplace; 
    Memo1.Lines.Add(RegEx.Replace(Edit1.Text, Pattern, Evaluator)); 
end; 
+1

捕捉那些你需要保留的部分,在替換模式中使用它們的反向引用。只匹配(並不捕獲)你需要刪除的內容。嘗試['(@F \ d {3} \(\ s * \ d {1,5} \ s *,\ s *)\ d {1,5}(\ s *,)'模式並替換爲' \ 1Fred \ 2'](https://regex101.com/r/8EUmya/1)。 –

+0

謝謝 - 我認爲我的主要問題是如何在Delphi代碼中實現。在Delphi文檔中沒有太多內容。你對此有任何指導? – CHEAPS

+1

@CHEAPS TRegex有一個重載替換方法,它不使用TMatchEvaluator,而是一個用於替換的模式(字符串)。您可能希望使用Wiktor提供的模式。 –

回答

1

當使用正則表達式替換,整個匹配的內容將被替換。您可以訪問整個比賽,捕獲的組和命名的捕獲組。

在Delphi中有兩種不同的方法。

您目前正在使用Evaluator,它是一個包含指令替代內容的對象方法。在這個方法裏面你可以訪問整個比賽內容。結果將是替換字符串。 如果vanilla正則表達式不能處理替換時想要做的事情(例如增加數字,改變charcase)

還有另一種重載替換方法,它使用字符串作爲替換。正如你想在這裏做一個基本的正則表達式替換,我會建議使用它。 在此字符串中,您可以反向引用您的匹配模式(整個匹配爲$0,捕獲組爲$Number,指定捕獲組爲${Name}),還可以添加所需的任何字符。

因此,您可以捕獲所有想要保留在組中的內容,然後在Wiktors評論中推薦反向引用。 正如你正在做一個替換,我會建議使用類函數TRegex.Replace,而不是創建正則表達式,然後替換。

Memo1.Lines.Add(
    TRegex.Replace(
    Edit1.Text, 
    '(@F\d{3}\(\s*\d{1,5}\s*,\s*)\d{1,5}(\s*,)', 
    '$1Fred$2')); 

PCRE正則表達式還支持\K(省略了之前的一切匹配)和向前看符號,它可以被用來捕捉正是你要替換的東西,像

Memo1.Lines.Add(
    TRegex.Replace(
    Edit1.Text, 
    '@F\d{3}\(\s*\d{1,5}\s*,\s*\K\d{1,5}(?=\s*,)', 
    'Fred')); 
相關問題