0

For some reason preg_replace is not working when the substitution includes curly braces {}.

If the original line is:

$Original_Line = "new_Journey('Iceland', {character: 'lidenbrock'}, {author : 'verne', destination : 'snæfellsjökull'})";

and the substitution (after pattern matching) is:

new_Journey('$1', [$3, $2])

giving the following pattern-match/substitution:

$Replacement_Line = preg_replace("/new_Journey\(\'([^\']+)\'\,\s*\{([^\}]+)\}\,\s*\{([^\}]+)\}\)\;/", "new_Journey('$1', [$3, $2])", $Original_Line);

the output is correct (albeit with square brackets [] instead of curly braces {}):

new_Journey('Iceland', [author : 'verne', destination : 'snæfellsjökull', character: 'lidenbrock']);

But if the substution uses curly braces {} instead of square brackets [] like this:

new_Journey('$1', {$3, $2})

the output is an error:

Parse error: syntax error, unexpected '3' (T_LNUMBER), expecting variable (T_VARIABLE) or '{' or '$' in [...][...] on line 5

Should I be escaping the curly braces {} in the substitution? If so, how?

Toto
  • 89,455
  • 62
  • 89
  • 125
Rounin
  • 27,134
  • 9
  • 83
  • 108
  • 1
    @wiktor-stribiżew can you explain the dup flag here. The unquoted `$2` put it in PHP context in the dup. Quoted it should pass to the PCRE processor as `"$2"` would. This question is specifically about why `"{$2}"` fails to compile. This seem unrelated to me. All of the dup answers go into validity of variable names but if that is the case `"$2"` should also be invalid, which it is not. – user3783243 Dec 29 '19 at 06:46
  • 1
    The only problem in this question is the PHP string literal syntax. The rest is not relevant, hence it **is a duplicate**. – Wiktor Stribiżew Dec 30 '19 at 01:10
  • I am still curious as to why the regex backreference in `"[$2]"` is parsed correctly, while in `"{$2}"` it is not. – Rounin Dec 30 '19 at 01:32

2 Answers2

1

Curly braces instead of a doubly-quoted string has some explicit uses in PHP, so in your case it might be that PHP thinks that you want to declare a variable when it sees the open curly braces since you can do the following:

$var = "bananas";
$test = "{$var} are yummy" // Will execute: bananas are yummy

You can replace the whole string to have a single quote and escape $1 as follows:

'new_Journey(\'$1\', {$3, $2})'

Since the above explanation do not apply on single quotes.

Tomer Gal
  • 933
  • 12
  • 21
  • 1
    Thanks. Good work. Using single quotes (and escaping literal single quotes) is a great alternative approach to using double quotes and escaping `$` signs. – Rounin Dec 29 '19 at 00:30
0

The $ must be escaped because PHP is trying to expand the $3 to a variable but variable names in PHP can't be just numbers.

"new_Journey('$1', {\$3, \$2})"
user3783243
  • 5,368
  • 5
  • 22
  • 41
  • Ah. Got it. Essentially, inside double quotes, PHP cannot discern between a `$` indicating a regex backreference and a `$` indicating a PHP variable. Thanks very much for that clarification. – Rounin Dec 29 '19 at 00:27
  • 1
    @RouninsaysJesuisMonica Well actually no, the `$3` should be valid, it roughly a backreference and is not meant to be a PHP variable. As can be seen here https://3v4l.org/p0EKR outside curlies works fine. Where as https://3v4l.org/F83Fl. This seems to be a PHP error to me. Wish the downvoter would have commented so it could be discussed further. Dup also seems incorrect, `$2` from dup is being used in PHP context, not for the PCRE processor. – user3783243 Dec 29 '19 at 06:41
  • 1
    @Rounin There are a lot of duplicates with SQL so I think the dups there are usually useful. However I think one user with super privileges to close is incorrect. 3-5 users should agree on the dup... or 2 users disagreeing should supercede 1 user's close vote, or put it into an appeal process. For future reference I've submitted this as a bug to PHP, can be monitored here, https://bugs.php.net/bug.php?id=79044. I'll update if a solution comes in there, or a explanation of the behavior. – user3783243 Dec 29 '19 at 21:26