tags:

views:

447

answers:

5

I have a regex that is going to end up being a bit long and it'd make it much easier to read to have it across multiple lines.

I tried this but it just barfs.

preg_match('
                ^J[0-9]{7}:\s+
                (.*?)             #Extract the Transaction Start Date msg
                \s+J[0-9]{7}:\s+Project\sname:\s+
                (.*?)             #Extract the Project Name
                    \s+J[0-9]{7}:\s+Job\sname:\s+
                (.*?)             #Extract the Job Name
                \s+J[0-9]{7}:\s+
                ', $this->getResultVar('FullMessage'), $atmp);

Is there are way to pass a regex in the above form to preg_match?

+3  A: 

You can use the extended syntax:

preg_match("/
    test
/x", $foo, $bar);
Konrad Rudolph
A: 

OK, here's a solution:

preg_match(
                '/(?x)^J[0-9]{7}:\s+
                (.*?)             #Extract the Transaction Start Date msg
                \s+J[0-9]{7}:\s+Project\sname:\s+
                (.*?)             #Extract the Project Name
                \s+J[0-9]{7}:\s+Job\sname:\s+
                (.*?)             #Extract the Job Name
                \s+J[0-9]{7}:\s+/'
                , $this->getResultVar('FullMessage'), $atmp);

The key is (?x) at the beginning which makes whitespace insignificant and allows comments.

It's also important that there's no whitespace between the starting and ending quotes and the start & end of the regex.

My first attempt like this gave errors:

preg_match('
                /(?x)^J[0-9]{7}:\s+
                (.*?)             #Extract the Transaction Start Date msg
                \s+J[0-9]{7}:\s+Project\sname:\s+
                (.*?)             #Extract the Project Name
                \s+J[0-9]{7}:\s+Job\sname:\s+
                (.*?)             #Extract the Job Name
                \s+J[0-9]{7}:\s+/
           ', $this->getResultVar('FullMessage'), $atmp);

What Konrad said also works and feels a little easier than sticking (?x) at the beginning.

Mark Biek
A: 

In PHP the comment syntax looks like this:

(?# Your comment here)

preg_match('
            ^J[0-9]{7}:\s+
            (.*?)             (?#Extract the Transaction Start Date msg)
            \s+J[0-9]{7}:\s+Project\sname:\s+
            (.*?)             (?#Extract the Project Name)
                \s+J[0-9]{7}:\s+Job\sname:\s+
            (.*?)             (?#Extract the Job Name)
            \s+J[0-9]{7}:\s+
            ', $this->getResultVar('FullMessage'), $atmp);

For more information see the PHP Regular Expression Syntax Reference

You can also use the PCRE_EXTENDED (or 'x') Pattern Modifier as Mark shows in his example.

Huppie
A: 
  • You should add delimiters: the first character of the regex will be used to indicate the end of the pattern.
  • You should add the 'x' flag. This has the same result as putting (?x) at the beginning, but it is more readable imho.
rix0rrr
+1  A: 

Yes, you can add the /x Pattern Modifier.

This modifier turns on additional functionality of PCRE that is incompatible with Perl. Any backslash in a pattern that is followed by a letter that has no special meaning causes an error, thus reserving these combinations for future expansion. By default, as in Perl, a backslash followed by a letter with no special meaning is treated as a literal. There are at present no other features controlled by this modifier.

For your example try this:

preg_match('/
              ^J[0-9]{7}:\s+
              (.*?)             #Extract the Transaction Start Date msg
              \s+J[0-9]{7}:\s+Project\sname:\s+
              (.*?)             #Extract the Project Name
              \s+J[0-9]{7}:\s+Job\sname:\s+
              (.*?)             #Extract the Job Name
              \s+J[0-9]{7}:\s+
            /x', $this->getResultVar('FullMessage'), $atmp);
Joseph Pecoraro