Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP preg_replace_回调,只替换1个backreference?_Php_Regex_String_Replace - Fatal编程技术网

PHP preg_replace_回调,只替换1个backreference?

PHP preg_replace_回调,只替换1个backreference?,php,regex,string,replace,Php,Regex,String,Replace,使用preg\u replace\u callback,是否可以只替换一个反向引用?还是我必须把整件东西都还回去 我只是想用引号把令牌的默认值括起来 $str = 'This is a {$token|token was empty}'; $str = preg_replace_callback('~{\$\w+\|(.*)?}~i', function($match) { //$match[1] is "token was empty" //I want to just rep

使用
preg\u replace\u callback
,是否可以只替换一个反向引用?还是我必须把整件东西都还回去

我只是想用引号把令牌的默认值括起来

$str = 'This is a {$token|token was empty}';
$str = preg_replace_callback('~{\$\w+\|(.*)?}~i', function($match) {
    //$match[1] is "token was empty"
    //I want to just replace $match[1], but it needs me to return the whole thing
}, $str);

我是否必须获取更多的反向引用,以便能够构建令牌的新版本并返回,我不能仅仅替换反向引用1?谢谢。

您将希望使用如下正则表达式:

~\{\$(\w+?)(?:\|(.+?))?\}~i
然后,您可以很容易地看到传递给回调的内容:

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

array(3) {
  [0]=>
  string(24) "{$token|token was empty}"
  [1]=>
  string(5) "token"
  [2]=>
  string(15) "token was empty"
}
string(22) "Foo: foo, Bar: not set"
从那里,您可以检查是否设置了
$match[1]
,如果设置了,则返回其值,否则返回
$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);
输出:

array(3) {
  [0]=>
  string(24) "{$token|token was empty}"
  [1]=>
  string(5) "token"
  [2]=>
  string(15) "token was empty"
}
string(22) "Foo: foo, Bar: not set"
注意:我在这里使用的
$GLOBALS
仅用于演示目的。如果可能的话,我建议使用PHP5.4的闭包绑定,因为您可以将闭包指定为一个特定的对象作为上下文(例如,您的模板/视图对象或任何包含您试图替换的变量的对象)。如果您没有使用PHP5.4,您还可以使用语法
函数($match)use($obj)
,其中
$obj
是您的上下文,然后在闭包中检查
isset($obj->{$match[1]})

我是否必须获取更多的反向引用,以便能够构建令牌的新版本并返回,我不能仅仅替换反向引用1

您有两个选择:

  • 如您所说,使用额外的反向引用来构造替换字符串,或者
  • 使用lookarounds仅匹配要替换的零件
  • 通常我建议使用第一种方法,因为第二种方法效率稍低,并且在某些情况下会导致无效匹配(向前看和向后看可能重叠)。在这种情况下,tho没有问题

    第二种选择的例子是:

    preg_replace_callback('~{\$\w+\|\K(?:[^{}]+)?(?=})~i', function($match){
        // $match[0] contains what used to be the first capturing group.
        // return the value you want to replace it with
        // (you can still use the capturing group if you want, but it's unnecessary)
    });
    
    • \K
      是一种将之前的所有内容从实际匹配中排除的方法(就像我们在后面有一个可变长度的查找)
    • (?=})
      是一个前瞻,表示以下内容必须是一个
      }
      ,但不包括在匹配自身中

    我最近想出了一种更简单的方法。 例如如果我想匹配
    \w+\d+\w+
    ,只更改数字

    $value = preg_replace_callback('~(\w+)(\d+)(\w+)~', function($match) {
        $match[2] = $match[2] * 2;//Do whatever I want to $match[2]
        return $match[1] . $match[2] . $match[3];
    }, $value);
    

    非常干净

    我很确定这是不可能的。非常酷,但肯定有点神秘。@Stephen,您可以使用
    /x
    ,例如:
    '/{$\w+\\\K[^{}]*(?=})/ix'
    (还删除了无用的组)