Reputation: 79
I'm having a bit of a problem that I am obviously unable to solve. It involves PCRE implementing negative lookahead AND behind conditions that should (but obviuosly don't) work together.
I have a string containing a constant in a JavaScript compliant syntax. This string's syntax needs to be converted to be adhering to JSON standards.
When I try to encapsulate the object property keys with quotation marks, I need to distinct "real" property keys from strings contained in an array, that happen to look like property keys.
const Const = {
propertyKeyA: "someValue",
propertyKeyB: ["ThisIsMyHeadache:ItShouldNotBeChanged"]
};
{
"propertyKeyA": "someValue",
"propertyKeyB": ["ThisIsMyHeadache:ItShouldNotBeChanged"]
}
$output = preg_replace(
'~(?:^|\b) (?![\'"]) (\w+) (?<![\'"]) :~mx',
'"\1":',
$input
);
which leads to:
{
"propertyKeyA": "someValue",
"propertyKeyB": [""ThisIsMyHeadache":ItShouldNotBeChanged"]
}
Notice the double quotation marks in the array definition. It seems to me as if the conditions do not work at all.
Does anyone have an idea on how to solve this? It would be immensely appreciated!
Best, Chris
Upvotes: 1
Views: 91
Reputation: 79
As posted by Wiktor in the comments to my initial question, this is the solution:
'~(?:^|\b) (?<![\'"]) (\w+) (?![\'"]) :~mx'
Upvotes: 0
Reputation: 626689
You mixed lookahead and lookbehind positions.
The (?![\'"])(\w+)
is equal to (\w+)
because (?![\'"])
is a negative lookahead and requires the next char not to be a '
or "
, but since the next pattern is \w
, matching a word char, the lookahead becomes redundant. You need to use a negative lookbehind here, (?<![\'"]) (\w+)
. And the problem with (\w+)(?<![\'"])
is similar: the word char cannot be a '
and "
and the negative lookbehind is redundant. You wanted a lookahead here.
You need to use
'~(?:^|\b) (?<![\'"]) (\w+) (?![\'"]) :~mx'
See the regex demo.
Upvotes: 1