Search code examples
regexvb.netif-statementenvdtereplacewith

ReplaceWith Conditional DTE


I want to match the terms "TextCtrls" and "LabelCtrls". When I find "TextCtrls" I want to replace with "Txt" and when I find "LabelControls" I want to replace with "Lbl". Online Demo

Is this possible with DTE.Find.ReplaceWith?

DTE.Find.FindWhat = "Container\(""\w+""\)\.(?:TextCtrls|LabelCtrls)\(""(?<ControlName>\w+)""\).Text"

DTE.Find.ReplaceWith = "<psydocode:Txt|Lbl>${ControlName}.Text"

Solution

  • Solution 1: Reusing the text present in input string

    Since the text you want to replace with actually is present in the source text, you may (ab)?use the capturing groups here the following way:

    DTE.Find.FindWhat = "Container\(""\w+""\)\.(?:(?<f>T)e(?<s>xt)Ctrls|(?<f>L)a(?<s>b)e(?<t>l)Ctrls)\(""(?<ControlName>\w+)""\).Text"
    DTE.Find.ReplaceWith = "${f}${s}${t}NameOfControl.Text"
    

    See the .NET regex demo

    Groups f, s and t are filled with the necessary bits of text and only have text if the corresponding alternatives match.

    enter image description here

    Solution 2: Using MatchEvaluator for custom replacement logic

    You may use MatchEvaluator to check what group matched or what group value is and then implement your own replacement logic:

    Dim s As String = "Container(""Name1"").TextCtrls(""Name2"").Text" & vbCrLf & "Container(""Name1"").LabelCtrls(""Name2"").Text"
    Dim pattern As String = "Container\(""\w+""\)\.(?<test>TextCtrls|LabelCtrls)\(""(?<ControlName>\w+)""\).Text"
    Dim result = Regex.Replace(s, pattern, New MatchEvaluator(Function(m As Match)
            If m.Groups("test").Value = "TextCtrls" Then
                Return "TxtNameOfControl.Text"
            Else
                Return "LblNameOfControl.Text"
            End If
        End Function))
    

    Output:

    enter image description here