1

Here is some PHP that I want to replace with something else.

Ks. <?kys(1959,"kysymys 1959")?>.
Ks. <?kys(1959)?>.

I have this regular expression, which finds both and works fine:

<\?kys\((\d+)(,"([\s\S]+)")?\)\?>

I tested (and designed) it with Regex101.com: https://regex101.com/r/kcDpN3/1

So there will at least be match $1. But there can also be matches $2 and $3. Is it possible to have preg_replace replace the matches with the following logic: if $3, use $3; else use $1?

2
  • 2
    Use preg_replace_callback Commented Sep 30, 2020 at 11:12
  • No, because it will just concatenate both matches, which isn't what I want. I want either or. Commented Sep 30, 2020 at 11:18

1 Answer 1

2

You may use preg_replace_callback.

See the PHP demo:

$str = 'Ks. <?kys(1959,"kysymys 1959")?>.
Ks. <?kys(1959)?>.';
$re = '/<\?kys\((\d+)(?:,"([^"]+)")?\)\?>/';

echo preg_replace_callback($re, function($m) {
    return empty($m[2]) ? $m[1] : $m[2];
}, $str);

Here, the second group in your pattern was turned into non-capturing one (?: added after () and now there are only two groups to handle.

The $m is the whole match object, and if Group 2 is empty, the replacement is Group 1 value ($m[1]). Else, it is Group 2 value, $m[2].

Note I also replaced [\s\S]+ with [^"]+ to make it match till the first ". Replace with .*? and add /s flag if there can be " inside Group 2.

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.