ar099968
ar099968

Reputation: 7537

Delphi TPerlRegEx ReplaceAll between 2 word

i have text like (with new line etc.), eg.:

[my_tag]foo[/my_tag]
  bar baz [my_tag]bar 
foo[/my_tag] 
foo [my_tag]bar baz
foo[/my_tag] 

i want totally remove all [my_tag][/my_tag] content, eg.:

[my_tag][/my_tag]
  bar baz [my_tag][/my_tag] 
foo [my_tag][/my_tag] 

my code not work (it seems not match newline):

var
  aPerlRegEx : TPerlRegEx;
  aContent   : string;
begin
  aContent := '';
  aContent := aContent + '[my_tag]foo[/my_tag]' + #13#10;
  aContent := aContent + 'bar baz [my_tag]bar ' + #13#10;
  aContent := aContent + 'foo[/my_tag] '        + #13#10;
  aContent := aContent + 'foo [my_tag]bar baz'  + #13#10;
  aContent := aContent + 'foo[/my_tag] '        + #13#10;

  aPerlRegEx := TPerlRegEx.Create;
  try
    with aPerlRegEx do begin
       Options     := [preCaseLess, preMultiLine];
       RegEx       := '\[my_tag\].*?\[\/my_tag\]';
       Subject     := aContent;
       Replacement := '';
    end;

    if aPerlRegEx.Match then
        aPerlRegEx.ReplaceAll;

    writeln(aPerlRegEx.Subject);
  finally
    FreeAndNil(aPerlRegEx);
  end;

Upvotes: 2

Views: 352

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626758

Since you say these tags cannot be nested, you can use your regex

\[my_tag\].*?\[\/my_tag\]

With the preSingleLine flag to make the . match newline symbols. See the regex demo (s option is used at the demo site).

Note that you can safely remove preMultiLine since you do not have ^ and $ in yout pattern to redefine the behavior of.

Or, you can unroll the lazy dot matching pattern for better performance:

\[my_tag\][^[]*(?:\[(?!\/my_tag\])[^[]*)*\[\/my_tag\]

See another regex demo. You do not have to use preSingleLine flag then as the negated character class [^[] match newlines, too.

Upvotes: 2

Related Questions