如何使用Delphi TRegEx替换特定的捕获组?

如何使用Delphi TRegEx替换特定的捕获组?,regex,delphi,delphi-xe7,Regex,Delphi,Delphi Xe7,我正在尝试使用DelphiXe7中的TRegex在字符串中进行搜索和替换 字符串看起来像“@FXXX(b,v)”,我想替换第二个整数值v。 例如: @F037(5942027,-99,-99,0,0,0) 可能成为 @F037(594,弗雷德,-99,-99,0,0,0) 我是RegEx的新手,但我创建了这样一个模式,它似乎可以很好地找到匹配项并确定“2027”的正确捕获组(以下括号中的部分)。这里是: @F\d{3}(\s*\d{1,5}\s*,\s*(\d{1,5})\s* 我的问题是,我无

我正在尝试使用DelphiXe7中的TRegex在字符串中进行搜索和替换

字符串看起来像“@FXXX(b,v)”,我想替换第二个整数值v。 例如: @F037(5942027,-99,-99,0,0,0)

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

我是RegEx的新手,但我创建了这样一个模式,它似乎可以很好地找到匹配项并确定“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;

使用正则表达式替换时,将替换整个匹配内容。您可以访问整个匹配、捕获组和命名捕获组

在Delphi中有两种不同的方法来实现这一点

您当前使用的是Evaluator,它是一个对象方法,包含要替换的指令。在此方法中,您可以访问整个匹配内容。结果将是替换字符串。 如果vanilla regex无法执行您希望在替换中执行的操作(例如,增加数字、更改字符大小写),则此方法非常有用

还有另一个重载替换方法,它使用字符串作为替换。由于您想在这里执行基本的正则表达式替换,我建议您使用它。 在此字符串中,您可以反向引用匹配的模式(
$0
表示整个匹配,
$Number
表示捕获的组,
${Name}
表示命名的捕获组),但也可以添加所需的任何字符

所以你们可以在小组中捕获你们想要保留的所有东西,然后按照评论中的建议进行反向引用。 由于您正在执行单个替换,我建议使用类函数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 regex还支持
\K
(省略之前匹配的所有内容)和lookaheads,它们可以用来准确捕获您想要替换的内容,如

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

捕获需要保留的部件,并在替换模式中使用对它们的反向引用。仅匹配(不捕获)您需要删除的内容。请尝试。谢谢-我想我的主要问题是如何在Delphi代码中实现。Delphi文档中没有太多内容。您能提供一些指导吗?@CHEAPS TRegex有一个重载替换方法,它不使用TMatchEvaluator,而是一个模式(字符串)用于替换。您可能希望将其与Wiktor提供的模式一起使用。