5

I have been trying to convert a regular expression from ruby to PHP, however I have had little luck.

This is the ruby regular expression:

QUOTED_LITERAL = /"[^"\\]*(?:\\.[^"\\]*)*"/
UNQUOTED_LITERAL = /[^\s=,][^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
LITERAL = /(#{QUOTED_LITERAL}|#{UNQUOTED_LITERAL})/
PAIR = /#{LITERAL}\s*=>\s*#{LITERAL}/

And this is my go in PHP:

 const PAIR = '/("[^"\\]*(?:\\.[^"\\]*)*"|[^\s=,][^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*)\s*=>\s*("[^"\\]*(?:\\.[^"\\]*)*"|[^\s=,][^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*)/';

However when I run

$result = preg_match_all(self::PAIR, $input, $matches);

I get the error:

preg_match_all(): Compilation failed: unmatched parentheses at offset 62


However when run it through, http://www.phpliveregex.com/ with the test data:

"foo" => "bar", "foo" => bar, foo => "bar"

it seems to work fine.

Not sure whats going on.

5
  • What's your version of PHP? Just do "php --version" Commented Aug 20, 2013 at 2:52
  • It is php 5.5.1. Living on the edge! Commented Aug 20, 2013 at 2:54
  • I've had several problems with php's preg_match in 5.4.2+. You might try a lower version, might fix your problem. Commented Aug 20, 2013 at 2:57
  • @adrian - Really? preg uses the same regexp library that most other programming languages (including ruby) do. I find it hard to believe that it should be buggy. Commented Aug 20, 2013 at 7:04
  • On infoarena.ro we use textile which relies on preg a lot. We've had the problem with a few versions of it on one particular page, though I can't remember exactly which one. Commented Aug 21, 2013 at 0:40

1 Answer 1

3

The problem lies with your backslashes.

I managed to get it to compile after removing all backslashes.

Then, I replaced all double slashes with 4 of them, and preg_match_all() was able to compile the regex too.

const PAIR = '/("[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|[^\s=,][^\s=,\\\\]*(?:\\\\.[^\s=,\\\\]*|=[^,>])*)\s*=>\s*("[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|[^\s=,][^\s=,\\\\]*(?:\\\\.[^\s=,\\\\]*|=[^,>])*)/';

You might have to edit it to get the exact regex you want. You had the compilation error because \\ was fed to the regex engine as \, which escaped the immediate square brackets. To encode a literal backslash, you need to use \\\\ - once for the string, and once for the regex engine.

string '\\\\'  --becomes--> regex \\ --becomes--> literal \

Ruby doesn't have this problem because its regex syntax is separate from its string syntax.

(Related question: preg_match(): Compilation failed: unmatched parentheses.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.