2

在 PHP 中,我有一个字符串 $string 和一个数组 $acronyms(格式为“UK”=>“United Kingdom”)。

现在我想用一些 HTML 标签替换 $string 中的所有首字母缩写词。例如Hello UK应该变成Hello <acronym title="United Kingdom">UK</acronym></pre>

我这样做:

foreach($acronyms as $acronym => $tooltip){
     $string = preg_replace('/'.$acronym.'/i', ''.$acronym.'', $string);
}

问题是:假设我有一个文本Hello UK和一个数组,用“United Kingdom”替换“UK”,用“RandomWord”替换“Kingdom”。然后文本将替换为Hello <acronym title="United <acronym title="RandomWord">Kingdom</acronym>">UK</acronym>显然是混乱的。

所以问题是:如何让我的 preg_replace 只查找不在<acronym>标签内的单词?(既不在标题属性中,也不在标签本身内)

编辑:根据响应进行第二次尝试(因为我无法回复代码)。仍然是同样的问题,首字母缩略词中的文本被第二次替换......

foreach($acronyms as $acronym => $tooltip){
        $acronyms[$acronym] = '<acronym title="'.$tooltip.'">'.$acronym.'</acronym>';
}
$string = str_ireplace(array_keys($acronyms), array_values($acronyms), $string);

4

3 回答 3

1

您可以使用strtr(). 执行替换后它不会重新扫描字符串:

foreach ($acronyms as $acronym => $tooltip) {
    $acronyms[$acronym] = sprintf('<acronym title="%s">%s</acronym>',
        htmlspecialchars($tooltip),
        htmlspecialchars($acronym)
    );
}

echo strtr($str, $acronyms);
于 2013-01-27T11:56:54.717 回答
0

不要试图用正则表达式做所有事情:

  1. 使用 HTML/XML 解析库解析您的 HTML。
  2. 遍历您的 HTML 标签,替换您必须替换的内容。
  3. 要求您的“html 解析库”将其转换回“HTML 字符串”。
于 2013-01-27T17:13:55.290 回答
0

这是正则表达式版本的尝试:

foreach($acronyms as $acronym => $tooltip){
    $rexp = '/' . $acronym . '(?!((?!<acronym).)*<\/acronym>)/i';
    $string = preg_replace($rexp, ''.$acronym.'', $string);
}

似乎对我有用。它执行以下操作:

  1. 将 $acronym 变量与否定前瞻匹配...
  2. 可以找到结束首字母缩略词标记的位置
  3. 但是当一个首字母缩写词标签在它之前时停止前瞻。

最终,这只匹配不在首字母缩略词标签内的地方(包括标题等所有属性)。

这是它的一个例子:gSkinner regex example

于 2013-01-27T11:46:10.473 回答