【发布时间】:2019-01-28 04:54:03
【问题描述】:
我正在尝试解析标记在两侧由@ 分隔的模板。
示例输入:
你好,@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,因为@ 之前已经用过了。输出是:
你好,彼得!请联系 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);
这正确匹配一对@s 之间包含的每个子字符串,但它不允许我自己替换分隔符。输出是:
你好,@彼得@!请联系 admin@example.com,亲爱的@Peter@!
如何将一对@s 之间的任何内容传递给回调,并将其替换为@s?
令牌将不包含换行符或@。
另一个例子
这有点人为,但显示我想要做什么,因为当前的建议依赖于单词边界。
输入
狗@猫@驴@斑马
我希望回调获取Cat 以查看是否应将@Cat@ 替换为令牌值,然后接收Donkey 以查看是否要替换@Donkey@。
【问题讨论】:
-
如果你知道变量名,那么用字符串替换
@name@而不是寻找任何@...@不是更容易吗? -
而不是过于宽泛的
.*匹配\w+。并在此之前使用回顾来断言没有字母。 -
@Devon 在实际代码中我运行数据库查询以查找是否已定义令牌。
-
@Džuris 请检查ideone.com/AYTjmk,如果您需要,我会发布。
-
好吧,如果你真的想匹配
@之间的任何字符,它也可能是ideone.com/Lm19Gc。
标签: php regex preg-replace-callback