1

I have a regex string that gets the value from a CSS code like that

body {
  background: #000;
}
/* drapeDecalage: 10px */

and I want to parse the commented drapeDecalage value.

For that I'm using regex, and I've made an expression like that:

(?<=\/\* drapeDecalage: )(.*?)(?=px \*\/)

which is perfectly working in PHP, but not in JavaScript, I've got this error

Uncaught SyntaxError: Invalid regular expression: /(?<=/* drapeDecalage: )(.*?)(?=px */)/: Invalid group

with this code:

var re = /(?<=\/\* drapeDecalage: )(.*?)(?=px \*\/)/; 
var str = '/* drapeDecalage: 10px */';

console.log(re.exec(str));

Demo at Regex101 with PHP PCRE https://regex101.com/r/nL2yX9/2

JavaScript code demo at JSFiddle: https://jsfiddle.net/wd574aw3/

What's wrong? How to fix that?

Thanks

1

1 Answer 1

2

It is a fact that current JavaScript regex engine does not support a lookbehind (no idea if/when it will be supported at all).

Thus, you need to remove the lookbehind (the ?<= part) from your PHP pattern and just match that subpattern, and get the value you need from the first capturing group (captured with (.*?)):

/\/\* drapeDecalage: (.*?)(?=px \*\/)/

See demo

var re = /\/\* drapeDecalage: (.*?)(?=px \*\/)/; 
var str = 'body {\n  background: #000;\n}\n/* drapeDecalage: 10px */';
if ((m = re.exec(str)) !== null) {
   document.body.innerHTML = m[1]; // m[1] contains the drapeDecalage value
}

Note that instead of literal spaces, you can use \s* to match zero or more whitespace.

Also, if you know there are only digits before px */, you can use (\d+) instead of (.*?) (lazy dot matching pattern is not the best construct to use when the type of data is known).

So, an alternative regex would look like:

/\/\*\s*drapeDecalage:\s*(\d+)(?=px\s*\*\/)/

See the regex demo

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

3 Comments

Working, thanks. Just waiting delay to valid your answer
In most cases, you do not need a lookbehind. This is one of them. Even in PHP, I'd advise to use capturing groups to retrieve such contextual values - regexps without lookbehinds at the pattern start usually perform better.
As usual, a nice and clear explanation with useful performance advice! I would just potentially alter the positive lookahead to accept an optional ; or even forget looking for the closing comment and just use (?=px\b).

Your Answer

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