PHP preg_replace_callback, replace only 1 backreference?

后端 未结 3 2048
一个人的身影
一个人的身影 2021-01-20 05:12

Using preg_replace_callback, is it possible to replace only one backreference? Or do I have to return the entire thing?

I\'m just trying to wrap the tok

3条回答
  •  深忆病人
    2021-01-20 05:50

    You'll want to use a regex like this, instead:

    ~\{\$(\w+?)(?:\|(.+?))?\}~i
    

    Then, you can easily see what's being passed to your callback:

    $str = 'This is a {$token|token was empty}';
    $str = preg_replace_callback('~\{\$(\w+?)(?:\|(.+?))?\}~i', function($match) {
        var_dump($match);
        exit;
    }, $str);
    

    Output:

    array(3) {
      [0]=>
      string(24) "{$token|token was empty}"
      [1]=>
      string(5) "token"
      [2]=>
      string(15) "token was empty"
    }
    

    And from there, you can check if $match[1] is set, and if so, return its value, otherwise, return $match[2]:

    $foo = 'foo';
    $str = 'Foo: {$foo|not set}, Bar: {$bar|not set}';
    $str = preg_replace_callback('~\{\$(\w+?)(?:\|(.+?))?\}~i', function($match) {
        if (isset($GLOBALS[$match[1]])) {
            return $GLOBALS[$match[1]];
        } else {
            return $match[2];
        }
    }, $str);
    var_dump($str);
    

    Output:

    string(22) "Foo: foo, Bar: not set"
    

    Note: I'm making use of $GLOBALS here for demonstration purposes only. I'd suggest making use of PHP 5.4's closure binding, if at all possible, since then you can assign the closure a specific object as context (e.g. your template/view object or whatever contains the variables you're trying to substitute). If you aren't using PHP 5.4, you can also use the syntax function($match) use ($obj), where $obj is your context, and then check isset($obj->{$match[1]}) inside your closure instead.

提交回复
热议问题