我有一个关联数组$dic
,我想用$dic
中相应的字符串替换HTML字符串中的href
链接。
$string = preg_replace("/<a href='"(.*?)'">(.*?)<'/a>/s", "$2->{$dic["$1"]}", $string);
上面的正则表达式没有按预期工作。但是在这种形式下它可以工作:
$string = preg_replace("/<a href='"(.*?)'">(.*?)<'/a>/s", "$2->$1", $string);
我想将<a>
标签存储为LinkText->LinkFromDic
。
复杂表达式 {$dic["$1"]}
中的"$1"
被解释为文字字符串"$1"
,因为:
- 在
preg_replace
替换之前处理复杂表达式 -
$1
是一个无效的PHP变量名:有效的变量名以字母或下划线开头,后面跟着任意数量的字母、数字或下划线。
很容易验证:
$dic = ['$1' => 'Dollar One'];
var_dump("{$dic["$1"]}");
输出string(10) "Dollar One"
旧的PHP版本支持e
正则表达式修饰符,它允许将替换字符串作为PHP代码计算。但是它在PHP 5.5.0中被弃用,并在PHP 7.0.0中被删除。
然而,php_replace_callback
函数足够灵活,可以解决这个问题:
$dic = ['/page/a' => 'Page A'];
$string = <<<'EOHTML'
<a href="/page/a">Link</a>
EOHTML;
$string = preg_replace_callback('/<a href'="(.*?)">(.*?)<'/a>/s',
function ($matches) use ($dic) {
$v = isset($dic[$matches[1]]) ? $dic[$matches[1]] : $matches[1];
return count($matches == 3) ? "{$matches[2]}->$v" : $matches[0];
}, $string);
var_dump($string);
输出string(12) "Link->Page A"