2016-10-03 7 views
2

私はDelphi XE7でTRegexを使用して検索を行い、文字列に置き換えようとしています。 、F037(594,2027、-99 @ -99,0,0:Delphi TRegExを使用して特定のキャプチャグループを置き換える方法は?

文字列は "@FXXX(B、V" のようになりますと、私は第2の整数値vを交換したいたとえば 。 、0,0)

は(594、フレッド、-99、-99,0,0,0,0)

私は正規表現での初心者ですが、そうです、このパターンを作っF037 @ になるかもしれません"2027"(以下のカッコ内の部分)の適切なキャプチャグループを特定するためにうまく動作するようにするには、次のように入力します(下の部分はカッコで囲んで示しています)。\ f \ d {3}(\ s * \ d { 5} \ s *、\ s *(\ d {1,5})\ s *

私の問題は、キャプチャされたグループ「2027」をDelphi TRegExの実装を使用して置き換える方法を考えることができないことです。私は、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

ようにあなたは維持する必要があり、これらの部分をキャプチャし、置き換えたい正確に何をキャプチャするために使用することができ、先読み、(前にマッチしたすべてのものを省略)\Kをサポートし、置換パターンでそれらの逆参照を使用します。削除する必要があるものだけをマッチさせてください(そしてキャプチャしないでください)。 \ d {1,5}(\ s *、)\ d {1,5} \ s *、\ s *)\ d {1,5}(\ s *、) 'パターンを試して、 \ 1Fred \ 2'](https://regex101.com/r/8EUmya/1) –

+0

ありがとうございます - 私の主な問題は、Delphiのコードに実装する方法です。あなたはそれについて何か指導しますか? – CHEAPS

+1

@CHEAPS TRegexには、TMatchEvaluatorを使用せず、置換するパターン(文字列)を使用するオーバーロード置換メソッドがあります。これをWiktorによって与えられたパターンで使いたいかもしれません。 –

答えて

1

は、全体の一致したコンテンツが置き換えられます。マッチ全体、キャプチャされたグループ、キャプチャされた名前付きグループにアクセスできます。

Delphiでこれを行う方法は2通りあります。

現在、評価者を使用しています。これは、置き換えるものについての指示を含むオブジェクトメソッドです。このメソッドの内部では、マッチコンテンツ全体にアクセスできます。結果は置換文字列になります。 この方法は、置換の際にバニラ正規表現ができない場合に便利です(数字の増加、文字の変更など)

文字列を置換文字として使用する別のオーバーロード置換メソッドがあります。基本的な正規表現をここで置き換えたいので、私はそれを使用することをお勧めします。 この文字列では、一致するパターン(照合全体では$0、キャプチャされたグループでは$Number、名前付きキャプチャグループでは${Name})を逆参照できます。また、任意の文字を追加できます。

したがって、グループに保存するすべてのものをキャプチャしてから、逆参照はWiktorsコメントで推奨されています。 あなたは1回の置換をしているので、Regexを作成して置き換えるのではなく、クラス関数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正規表現も

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