1
votes

I've got a lot of files (DFM Delphi source files) in which I would like to remove a specific property from all components of a specific class.

Each component definition starts with the word object or inherited, followed by:

  • Empty space
  • The name of the component (alphanumeric)
  • Colon :
  • Empty space
  • The class of the component (alphanumeric)

Following lines represents properties of the component and are composed by:

  • Property name (alphanumeric)
  • Empty space
  • Equals sign =
  • Empty space
  • Property value (alphanumeric)

There also could be other nested components, following the same syntax rules.

The component definition finishes with the end keyword. Here is an example:

inherited Test: TTest
  OtherProperty = 'Hello'
  inherited Component1: TTargetClass
    OtherProperty = 100
    TargetProperty = True
  end
  object Component1: TTargetClass
    OtherProperty = 'Hello'
  end
  object Component2: TPanel
    OtherProperty = 100
    TargetProperty = True
    object NestedComponent1: TTargetClass
      OtherProperty = 'Hello'
      TargetProperty = False
    end
  end
end

Probably it's not the best way for doing this but I want to accomplish my goal by using a RegEx in Notepad++. The property I want to remove is TargetProperty and I want to remove the lines who contains it only from components of class TTargetClass.

inherited Test: TTest
  OtherProperty = 'Hello'
  inherited Component1: TTargetClass
    OtherProperty = 100
  end
  object Component1: TTargetClass
    OtherProperty = 'Hello'
  end
  object Component2: TPanel
    OtherProperty = 100
    TargetProperty = True
    object NestedComponent1: TTargetClass
      OtherProperty = 'Hello'
    end
  end
end

I've tried the following RegEx but it matches from the first TTargetClass to the last end:

TTargetClass.*(TargetProperty.*\R)end
1
@WiktorStribiżew: It causes a little indentation's problem but it works also on notepad++Fabrizio
I wrote the pattern inside Notepad++, that is why it is working there :) As for indentation, it can only be "fixed" if you always have the same indentation in the matches. Is the indentation the same? Is it 2 tabs or 8 spaces?Wiktor Stribiżew
Ah, check this one. It seems to preserve the indentation.Wiktor Stribiżew
@WiktorStribiżew: Yes! thank you, post it as an answer so I can accept itFabrizio

1 Answers

1
votes

You may use

(TTargetClass(?:\R(?!\h*end$).*)*?)^\h*TargetProperty.*\R+(\h*end$)

and replace with $1$2. See the regex demo.

enter image description here

Details

  • (TTargetClass(?:\R(?!\h*end$).*)*?) - Group 1 capturing:
    • TTargetClass - a literal substring
    • (?:\R(?!\h*end$).*)*? - zero or more, but as few as possible, seuqences of:
      • \R(?!\h*end$) - a line break that is not followed with 0+ horizontal whitespaces (\h*) and then an end substring at the end of the line ($)
      • .* - the rest of the line
  • ^\h* - start of a line with 0+ horizontal whitespaces after
  • TargetProperty - a literal substring
  • .* - the rest of the line
  • \R+ - 1 or more line breaks
  • (\h*end$) - Group 2: 0+ horizontal whitespaces and end substring at the end of the line.

The $1 is a backreference that refers to the text captured with Group 1 and $2 refers to the text captured with Group 2.