使用preg_replace_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?感谢。
答案 0 :(得分:4)
我是否必须获取更多的反向引用,以便我能够构建一个新版本的令牌并返回它,我不能只替换反向引用1?
您有两种选择:
通常我建议使用第一种方法,因为第二种方法效率稍低,并且在某些情况下可能导致无效匹配(当前瞻和后方可能重叠时)。在这种情况下,没有问题。
第二个选项的示例是:
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
是一种从实际匹配中排除它之前的所有内容的方法(例如,如果我们在那里有一个可变长度的lookbehind)。(?=})
是一个预测,说以下必须是}
,但不会在自己的匹配中包含它。答案 1 :(得分:2)
你会想要使用这样的正则表达式,而不是:
~\{\$(\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"
}
从那里,您可以检查是否设置了$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);
输出:
string(22) "Foo: foo, Bar: not set"
注意:我在此处使用$GLOBALS
仅用于演示目的。我建议使用PHP 5.4的闭包绑定,如果可能的话,那么你可以为闭包分配一个特定的对象作为上下文(例如你的模板/视图对象或包含你试图替换的变量的任何东西) 。如果你没有使用PHP 5.4,你也可以使用function($match) use ($obj)
语法,其中$obj
是你的上下文,然后检查你的闭包内的isset($obj->{$match[1]})
。
答案 2 :(得分:0)
我最近提出了一种更简单的方法。
例如;如果我想匹配\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);
非常干净!