Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2007-11

PCRE

14 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

L

There is also:

http://www.renatomancuso.com/software/dpcre/dpcre.htm

(By the way, why all these people wrap PCRE in a class is beyond me. Object oriented PCRE.. defeats the bloody purpose of regular expressions in the first place - quick and dirty access to regexes must not be stored in a class. I repeat, must not. So I think we'll use these downloads as ideas and implement a proper PCRE wrapper unit that's easy to use quickly and dirtily (if that was a word))

Krishna
to Marco van de Voort
Marco van de Voort wrote 5 lines

then try this: http://www.renatomancuso.com/software/dpcre/dpcre.htm

I've used the above wrapper in a news ticker application without any problems. AFAIK, it still being used in 11 news channels on a daily basis.

Cheers,
-Krishna

One reason that life is complex is that it has a real part and an imaginary part -Andrew Koenig
L
to Marco van de Voort: Doing a dumb header port is not that hard. If you can't do it, start making tests, and…
Doing a dumb header port is not that hard. If you can't do it, start making tests, and I'll do it.

L505 loves flamebaits. They are what I eat for breakfast.

I personally like to spend my time doing useful things, and if someone has already made the translation then I'm not going to waste time on it. Just like I'm not going to rewrite a stringlist if there is already a stringlist in the RTL. Waste of time. I'd rather write a new data structure and make my time useful. Or I'd rather convert a header that hasn't already been converted.

So why use the JCL? Just do all the translations yourself.. forget JCL.

And yes, that means that not all programmers want to roll their own sysutils or system unit. Lots of them like to make use of something that's already been written for them. And as an API designer, I know this well.

L505

Marco van de Voort
to L
> Doing a dumb header port is not that hard. If you can't do it, start making > tests, and I'll do it.

(skip nonsense stuff)

So why use the JCL? Just do all the translations yourself.. forget JCL.

- JCL's license is MPL and thus not suitable for inclusion in FPC http://wiki.freepascal.org/licensing
- JCL is not in a runnable state for most FPC targets.
- translated Delphi headers are typically not clean for cross platform (most notably 64-bit) use.

S. Fisher
to Marco van de Voort
--- Marco van de Voort wrote 14 lines
> > Doing a dumb header port is not that hard. If you can't do it, start making > > tests, and I'll do it. (skip nonsense stuff) > So why use the JCL? Just do all the translations yourself.. forget JCL. - JCL's license is MPL and thus not suitable for inclusion in FPC http://wiki.freepascal.org/licensing - JCL is not in a runnable state for most FPC targets. - translated Delphi headers are typically not clean for cross platform (most notably 64-bit) use.

After making a few tiny changes to the Delphi source, I got this to compile and work:

http://www.renatomancuso.com/software/dpcre/dpcre.htm

The author says that he had to modify the C source and recompile in order to give Pascal access to all pcre features.

__________________________________________________ Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com

S. Fisher
to S. Fisher

Unfortunately, it's slightly slower than my fastest program that uses the library that comes with FPC. I wonder if the dll was compiled with all of the C compiler's optimiaztions turned on.

{$mode objfpc}
uses pcre; // from www.renatomancuso.com/software/dpcre/dpcre.htm

const
patterns : array[1..9] of pchar =
(
'agggtaaa|tttaccct',
'[cgt]gggtaaa|tttaccc[acg]',
'a[act]ggtaaa|tttacc[agt]t',
'ag[act]gtaaa|tttac[agt]ct',
'agg[act]taaa|ttta[agt]cct',
'aggg[acg]aaa|ttt[cgt]ccct',
'agggt[cgt]aa|tt[acg]accct',
'agggta[cgt]a|t[acg]taccct',
'agggtaa[cgt]|[acg]ttaccct'

    );
  replacements : array[0..10,0..1] of string[15] =
  (
    ('B', '(c|g|t)'), ('D', '(a|g|t)'), ('H', '(a|c|t)'), ('K', '(g|t)'),
    ('M', '(a|c)'), ('N', '(a|c|g|t)'), ('R', '(a|g)'), ('S', '(c|t)'),
    ('V', '(a|c|g)'), ('W', '(a|t)'), ('Y', '(c|t)')
  );
// Append 2 strings to an ansistring rapidly.  Note: the ansistring's
// length will be increased by a more than sufficient amount.
function append2( var dest: ansistring; len0: longint;
                  s1: pchar; len1: longint;
                  s2: pchar; len2: longint): longint; inline;
const  quantum = 599000;
var  newlength: longint;
begin
  newlength := len0 + len1 + len2;
  // Since setlength() is somewhat costly, we'll do it less
  // often than you would think.
  if length( dest ) < newlength then
    setlength( dest, newlength + quantum );
  move( s1^, dest[len0 + 1], len1 );
  move( s2^, dest[len0 + 1 + len1], len2 );
  exit( newlength );
end;
procedure replace_matches( const str: ansistring;  var dest: ansistring );
var
  rx : iregex;
  capture: imatch;
  start, index, truelength, i : longint;
  target, repl, found: string[255];
begin
  target := '[';
  for i := 0 to high(replacements) do
    target += replacements[i,0];
  target += ']';
  rx := regexCreate( target );
  dest := '';   truelength := 0;   start := 0;
  repeat
    capture := rx.match( str, start );
    if not capture.success then  break;
    index := capture.groups[0].index;
    found :=  str[ index + 1 ];
    repl := replacements[ pos(found,target)-2, 1 ];
    truelength := append2(
      dest, truelength, @str[start+1], index-start, @repl[1], length(repl) );
    start := index + 1;
  until false;
  setlength( dest, truelength );
  dest := dest + Copy( str, start+1, length(str) - start + 1);
end;
function count_matches( const needle, haystack: ansistring ):longint;
var
  rx : iregex;
  capture: imatch;
  where: longint;
begin
  rx := regexCreate( needle );
  result := 0;
  where := 0;
  repeat
    capture := rx.match( haystack, where );
    if not capture.success then  break;
    inc( result );
    where := capture.groups[0].index + capture.groups[0].length;
  until false;
end;
var
  pattern : pchar;
  sequence, new_seq : ansiString;
  line: string[255];
  i, count, init_length, clean_length: longint;
  inbuf : array[1..64*1024] of char;
begin
  settextbuf(input,inbuf);
  sequence := '';
  init_length := 0;
  while not eof do
  begin
    readln( line );
    init_length += length( line ) + 1;
    if line[1]  '>' then
      sequence := sequence + line;
  end;
  clean_length := length(sequence);
  for i := low(patterns) to high(patterns) do
  begin
    pattern := patterns[i];
    count := count_matches( pattern, sequence );
    writeln( pattern, ' ', count);
  end;
  replace_matches(sequence, new_seq);
  writeln;
  writeln( init_length );
  writeln( clean_length );
  writeln( length(new_seq) );
end.

__________________________________________________ Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com

Florian Klaempfl
to S. Fisher
Unfortunately, it's slightly slower

Why? This is great if our library is fast :)

Show quoted text 142 lines
than my fastest program that uses the library that comes with FPC. I wonder if the dll was compiled with all of the C compiler's optimiaztions turned on. {$mode objfpc} uses pcre; // from www.renatomancuso.com/software/dpcre/dpcre.htm const patterns : array[1..9] of pchar = ( 'agggtaaa|tttaccct', '[cgt]gggtaaa|tttaccc[acg]', 'a[act]ggtaaa|tttacc[agt]t', 'ag[act]gtaaa|tttac[agt]ct', 'agg[act]taaa|ttta[agt]cct', 'aggg[acg]aaa|ttt[cgt]ccct', 'agggt[cgt]aa|tt[acg]accct', 'agggta[cgt]a|t[acg]taccct', 'agggtaa[cgt]|[acg]ttaccct' ); replacements : array[0..10,0..1] of string[15] = ( ('B', '(c|g|t)'), ('D', '(a|g|t)'), ('H', '(a|c|t)'), ('K', '(g|t)'), ('M', '(a|c)'), ('N', '(a|c|g|t)'), ('R', '(a|g)'), ('S', '(c|t)'), ('V', '(a|c|g)'), ('W', '(a|t)'), ('Y', '(c|t)') ); // Append 2 strings to an ansistring rapidly. Note: the ansistring's // length will be increased by a more than sufficient amount. function append2( var dest: ansistring; len0: longint; s1: pchar; len1: longint; s2: pchar; len2: longint): longint; inline; const quantum = 599000; var newlength: longint; begin newlength := len0 + len1 + len2; // Since setlength() is somewhat costly, we'll do it less // often than you would think. if length( dest ) < newlength then setlength( dest, newlength + quantum ); move( s1^, dest[len0 + 1], len1 ); move( s2^, dest[len0 + 1 + len1], len2 ); exit( newlength ); end; procedure replace_matches( const str: ansistring; var dest: ansistring ); var rx : iregex; capture: imatch; start, index, truelength, i : longint; target, repl, found: string[255]; begin target := '['; for i := 0 to high(replacements) do target += replacements[i,0]; target += ']'; rx := regexCreate( target ); dest := ''; truelength := 0; start := 0; repeat capture := rx.match( str, start ); if not capture.success then break; index := capture.groups[0].index; found := str[ index + 1 ]; repl := replacements[ pos(found,target)-2, 1 ]; truelength := append2( dest, truelength, @str[start+1], index-start, @repl[1], length(repl) ); start := index + 1; until false; setlength( dest, truelength ); dest := dest + Copy( str, start+1, length(str) - start + 1); end; function count_matches( const needle, haystack: ansistring ):longint; var rx : iregex; capture: imatch; where: longint; begin rx := regexCreate( needle ); result := 0; where := 0; repeat capture := rx.match( haystack, where ); if not capture.success then break; inc( result ); where := capture.groups[0].index + capture.groups[0].length; until false; end; var pattern : pchar; sequence, new_seq : ansiString; line: string[255]; i, count, init_length, clean_length: longint; inbuf : array[1..64*1024] of char; begin settextbuf(input,inbuf); sequence := ''; init_length := 0; while not eof do begin readln( line ); init_length += length( line ) + 1; if line[1] '>' then sequence := sequence + line; end; clean_length := length(sequence); for i := low(patterns) to high(patterns) do begin pattern := patterns[i]; count := count_matches( pattern, sequence ); writeln( pattern, ' ', count); end; replace_matches(sequence, new_seq); writeln; writeln( init_length ); writeln( clean_length ); writeln( length(new_seq) ); end. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
L
to S. Fisher: After making a few tiny changes to the Delphi source, I got this to compile and work:…
Show quoted text 5 lines
> > Doing a dumb header port is not that hard. If you can't do it, start > > making > > tests, and I'll do it. (skip nonsense stuff)

No, not nonsense. Jeff P. (yetanothergeek) had a header for freepascal not using any JCL, AFAIK. Which is the original link I provided, which wasn't working. Which is why I posted this to the mailing list.

He did it for us already, AFAIK. No sense repeating Jeff's work if he already did it.

Show quoted text 5 lines
> So why use the JCL? Just do all the translations yourself.. forget JCL. - JCL's license is MPL and thus not suitable for inclusion in FPC http://wiki.freepascal.org/licensing

Because of the ridiculous GPL license which freepascal uses, which isn't as free as a BSD/NRCOL license.
That's not JCL's problem, that is freepascal and GPL's problem. Blame it on them.

- JCL is not in a runnable state for most FPC targets. - translated Delphi headers are typically not clean for cross platform (most notably 64-bit) use.

Jeff's unit may have been, for all you know, which is the unit that I supplied a uRL to in my first email. Which I cannot download, and am waiting for Jeff to reply. In the mean time, S. Fisher has already got a unit working while we were yapping.

L505

L
Show quoted text 5 lines
> > Doing a dumb header port is not that hard. If you can't do it, start > > making > > tests, and I'll do it. (skip nonsense stuff)

No, not nonsense. Jeff P. (yetanothergeek) had a header for freepascal not using any JCL, AFAIK. Which is the original link I provided, which wasn't working. Which is why I posted this to the mailing list.

He did it for us already, AFAIK. No sense repeating Jeff's work if he already did it.

Show quoted text 5 lines
> So why use the JCL? Just do all the translations yourself.. forget JCL. - JCL's license is MPL and thus not suitable for inclusion in FPC http://wiki.freepascal.org/licensing

Because of the ridiculous GPL license which freepascal uses, which isn't as free as a BSD/NRCOL/MIT license.

That's not JCL's problem, that is freepascal and GPL's problem. Blame it on them.

Freedoom can go both ways. Although I think you are a BSD fan and I am patronizing anyway.

- JCL is not in a runnable state for most FPC targets. - translated Delphi headers are typically not clean for cross platform (most notably 64-bit) use.

Jeff's unit may have been, for all you know, which is the unit that I supplied a uRL to in my first email. Which I cannot download, and am waiting for Jeff to reply. In the mean time, S. Fisher has already got a unit working while we were yapping.

L505

S. Fisher
to L
--- L wrote 14 lines
> - JCL is not in a runnable state for most FPC targets. > - translated Delphi headers are typically not clean for cross platform > (most > notably 64-bit) use. Jeff's unit may have been, for all you know, which is the unit that I supplied a uRL to in my first email. Which I cannot download, and am waiting for Jeff to reply. In the mean time, S. Fisher has already got a unit working while we were yapping. L505

For everbody who wants pcre, here's how I got it working.

download "PCRE 6.7 DLL".

To the file PCRE.pas, apply the attached patch file. If you don't, there will be errors during compiling.

I couldn't find any documentation. This quick and dirty little program may help.

{$mode delphi}
uses pcre;
function count_matches( const needle, haystack: ansistring ):longint;
var
  rx : iregex;
  capture: imatch;
  where: longint;
begin
  rx := regexCreate( needle );
  result := 0;
  where := 0;
  repeat
    capture := rx.match( haystack, where );
    if not capture.success then  break;
    inc( result );
    where := capture.groups[0].index + capture.groups[0].length;
  until false;
end;
var
  rx : iregex;
  capdata: imatch;
  md : idfamatchCollection;
  str: ansistring;
  i : integer;
begin
  str := 'Come back, Mac.';
  rx := regexCreate( '(\w*)a(\w*)' );
  capdata := rx.match( str );
  if capdata.success then
  begin
    writeln( 'found' );
    writeln( capdata.groups.count, ' captures' );
    for i:= 0 to capdata.groups.count - 1 do
      writeln( ' ', capdata.groups[i].index, ' ', capdata.groups[i].length,
        '  value: ', capdata.groups[i].value );
    writeln;
  end
  else
    writeln( 'not' );
  writeln;
  md := rx.dfaMatch( str );
  writeln( 'count: ', md.count );
  if md.count > 0 then
  begin
    writeln( 'dfamatch won' );
    writeln( md[0].index, ' ', md[0].length,' ', md[0].value );
  end
  else
    writeln( 'dfamatch failed' );
  writeln;
  writeln('counting matches');
  writeln( count_matches( 't', 'try to do it' ));
end.

__________________________________________________ Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com