Regular expressions

Cyclone has an interface to the [Perl Compatible Regular Expressions][1] (PCRE) library.

Here’s a Perl program that does a simple substitution:

my $x = "Hello, Bob";
$x =~ s/Bob/World/;
print $x, "\n";

It prints “Hello, World.” The equivalent Cyclone program is

#include <stdio.h>
#include <pcre.h>

int main() {
  let x = "Hello, Bob";
  let y = pcre_s(x,"Bob","World",0);
  return 0;

You need to compile this program with the -lpcre flag.

A global replacement, like the Perl s/foo/bar/g, is done with

y = pcre_s_g(x,"foo","bar",0);

The last argument of pcre_s and pcre_s_g allows you to set options for the substitution. For example the Perl s/(foo|bar)baz/$1/gms corresponds to

y = pcre_s_g(x,"(foo|bar)baz","$1",PCRE_MULTILINE|PCRE_DOTALL);

The options you can pass this way are PCRE_MULTILINE (for m), PCRE_DOTALL (for s), PCRE_CASELESS (for i), and PCRE_EXTENDED (for x).

The Perl option e allows you to execute Perl statements at each match in the substitution, for example,


matches every word in upper case only, and converts that text to lower case using the function lc. The result of the evaluation should be a string that is the replacement value.

The equivalent in Cyclone would be

y = PCRE_S_EG(x,"([A-Z]+)",
              ({ let one = DOLLAR(1);
                 STRING(lc(one)); }),

PCRE_S_EG is a macro. The third argument of the macro is an expression to be executed at each match. Here, we have used a statement expression, which allows us to use declarations, etc. The macro DOLLAR returns a new, heap-allocated copy of the corresponding match (so DOLLAR(1) is like $1 in Perl). The macro STRING adds its argument to the replacement text.