我正在尝试解析在两边用@
分隔令牌的模板。
示例输入:
你好,@ name @!请联系admin@example.com,亲爱的@name @!
所需的输出:
你好,彼得!亲爱的彼得,请联系admin@example.com!
天真的尝试找到匹配项并替换:
$content = 'Hello, @name@! Please contact admin@example.com, dear @name@!';
preg_replace_callback(
'/(@.*@)/U', function ($token) {
if ('@name@' == $token) //replace recognized tokens with values
return 'Peter';
return $token; //ignore the rest
}, $content);
此正则表达式无法正确处理备用@
-它匹配第一个@name@
和@example.com, dear @
,但不匹配第二个@name
,因为一个{{1} }已经花完了。输出为:
你好,彼得!请联系admin@example.com,亲爱的@name @!
为防止花费@
,我尝试使用环顾四周:
@
这正确匹配了一对$content = 'Hello, @name@! Please contact admin@example.com, dear @name@!';
preg_replace_callback(
'/(?<=@)(.*)(?=@)/U', function ($token) {
if ('name' == $token) //replace recognized tokens with values
return 'Peter';
return $token; //ignore the rest
}, $content);
之间包含的每个子字符串,但不允许我替换定界符本身。输出为:
你好,@ Peter @!请联系admin@example.com,亲爱的@Peter @!
如何传递在一对@
之间进行回调的所有内容,并替换掉@
之间的内容?
令牌不会包含换行符或@
。
这有点人为,但是为了展示我想做的事情,因为当前的建议依赖于单词边界。
输入
狗@猫@驴@斑马
我希望回溯获取@
来查看是否应将Cat
替换为令牌值,然后接收@Cat@
来查看是否要替换Donkey
。
答案 0 :(得分:1)
我建议使用:/@\b([^@]+)\b@/
Capture group0 holds: @name@
Capture group1 holds: name
答案 1 :(得分:1)
由于定界符可能重叠,因此我不确定可以使用正则表达式来做到这一点。但是,这里有一个递归函数可以完成任务。这段代码并不关心令牌的外观(即不必是字母数字),只要它出现在@
个符号之间即可:
function replace_tokens($tokens, $string) {
$parts = explode('@', $string, 3);
if (count($parts) < 3) {
// none or only one '@' so can't be any tokens to replace
return implode('@', $parts);
}
elseif (in_array($parts[1], array_keys($tokens))) {
// matching token, replace
return $parts[0] . $tokens[$parts[1]] . replace_tokens($tokens, $parts[2]);
}
else {
// not a matching token, try further along...
// need to replace the `@` symbols that were removed by explode
return $parts[0] . '@' . $parts[1] . replace_tokens($tokens, '@' . $parts[2]);
}
}
$tokens = array('name' => 'John', 'Cat' => 'Goldfish', 'xy zw' => '45');
echo replace_tokens($tokens, "Hello, @name@! Please contact admin@example.com, dear @name@!") . "\n";
echo replace_tokens($tokens, "Dog@Cat@Donkey@Zebra") . "\n";
echo replace_tokens($tokens, "auhdg@xy zw@axy@Cat@") . "\n";
$tokens = array('Donkey' => 'Goldfish');
echo replace_tokens($tokens, "Dog@Cat@Donkey@Zebra") . "\n";
输出:
Hello, John! Please contact admin@example.com, dear John!
DogGoldfishDonkey@Zebra
auhdg45axyGoldfish
Dog@CatGoldfishZebra