3

Is there an easy way to do a RegExp replace in FreePascal/Lazarus?

Hunting around I can see that I can do a match fairly easily, but I'm struggling to find functions to do a search and replace.

What I'm trying to acheive is as follows.

  • I have an XML file loaded into a SynEdit component.
  • The XML file has a decalaration at the start
  • The DTD is held in a seperate file.
  • I don't want to combine the two in one file, but I do wantto validate the XML as it is being editted.
  • I'm reading the XML into a string variable and I want to insert the DTD between the and the XML content in a temporary string variable (to create a compliant XML with self contained DTD) that can be parsed and validated.

So essentially I have:

<?Line1?>
Line2
Line3

And I want to do a RegExp type search and replace for '<?Line1?>' replaceing with '<?Line1?>\n<![DTD\nINFO WOULD\nGO HERE\n!]' to give me:

<?Line1?>
<![DTD
INFO WOULD
GO HERE
!]
Line2
Line3

For example in PHP I would use:

preg_replace('/(<\?.*\?>)/im','$1
<![DTD
INFO WOULD
GO HERE
!]',$sourcestring);

But there doesn't seem to be an equivalent set of regexp functions for FreePascal / Lazarus - just a simple/basic RegExp match function.

Or is there an easier way without using regular expressions - I don't want to assume that the declaration is always there in the correct position on Line 1 though - just to complicate things.

Thanks,

FM

Fat Monk
  • 2,077
  • 1
  • 26
  • 59
  • 1
    I avoid regexes generally, but afaik there are PCRE header conversions out there. – Marco van de Voort Mar 27 '13 at 21:26
  • That's got me searching in the right direction, I think. Found a few Delphi compatible wrapped versions so just got to figure out how to integrate into Lazarus now. – Fat Monk Mar 28 '13 at 08:27
  • Thanks @Marco-van-de-Voort. I've downloaded `TPerlRegEx` which seems to be a pretty good library from reading around, but I cannot figure out or find any documentation about how to integrate a Delphi library package (I'm aware that this may not be a particulary correct term) into Lazarus. Can anyone give me any pointers? – Fat Monk Apr 11 '13 at 09:10
  • Don't. That is only necessary for (designtime) controls. Get the basic unit, and simply put it where the compiler can find it. Probably the package contains tedits with regex validator or so. – Marco van de Voort Apr 11 '13 at 18:48
  • Well I'm getting part way there, but still gettings errors. I downloaded TPerlRegEx from [link](http://www.regular-expressions.info/delphi.html), put it in its own directory under components in the lazarus directory, added the unit to my project and to the use clause of the unit that will use it but got compile errors. I then Ran Tools->Convert Delhi unit on PerlRegEx.pas which seems to have corrected compile time errors with that, but when I do the same with pcre.pas I get and error about the data type `external` in a function declaration and the same if I try to compile without converting. – Fat Monk Apr 12 '13 at 13:50
  • Make sure that you use delphi mode. FPC mode is more picky about recycling semi reserved identifires – Marco van de Voort Apr 14 '13 at 15:49
  • I've added `{$Mode Delphi}` to both .pas files (PerlRegEx.pas actually already had it from the conversion I guess) but I'm still getting the same errors: `C:\lazarus\components\perlregex\pcre.pas(626,33) Error: Identifier not found "external"` and `C:\lazarus\components\perlregex\pcre.pas(632,30) Error: Fields cannot appear after a method or property definition, start a new visibility section first`. I'm trawling the lazarus/fpc wiki but not finsing much that seems relevent =. – Fat Monk Apr 15 '13 at 09:04
  • Why do you need a regex for this? You could do this easily with a couple of stringlists. Load the XML into a stringlist, find the line containing `` using `IndexOf`. Insert from 0 to that index into a second stringlist, add your DTD text to that second stringlist, and then append the remaining items from the first stringlist to the second one. The second stringlist now contains the combined XML and DTD to use however you like. – Ken White Oct 31 '14 at 15:55
  • here you can read on about the PCRE2 library which supports searc-and-replace http://www.regular-expressions.info/pcre.html – macf00bar May 13 '15 at 14:29

1 Answers1

2

As far as I know, the PerlRegEx unit isn't compatible with Free Pascal. But you can use the RegExpr unit, which comes with Free Pascal.

If I understand correctly, you want a replacement with substitution. Here is a simple example that you can adapt to your need.

{$APPTYPE CONSOLE}
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}

uses
  regexpr;

var
  s: string;

begin
  s := 'My name is Bond.';

  s := ReplaceRegExpr(
    'My name is (\w+?)\.',
    s,
    'His name is $1.',
    TRUE // Use substitution
  );

  WriteLn(s); // His name is Bond.
  ReadLn;
end.