0

我需要根据以下规则对我的 html 页面属性标题中的每个链接执行正则表达式:

  1. 链接等于锚文本。
  2. 该链接没有标题属性。

我写了这段代码:

$x = 'gg <a href="#">Anchor 1</a>, <a href="#" title="text">Anchor 2</a>';
echo preg_replace('/\<a([^<]*)(?!title)>([^<]+)\<\/a/isu', '<a${1} title="${2}">${2}</a', $x);

但我得到了这个意想不到的结果:

gg <a href="#" title="Anchor 1">Anchor 1</a>, <a href="#" title="text" title="Anchor 2">Anchor 2</a>

第二个链接有 2 个标题属性。为什么这不能按预期工作?我该如何解决?

4

1 回答 1

1

在你的表达中:

<a([^<]*)

这一直匹配到下一个左括号,但被>表达式中的下一个停止;同时它跳过了(?!title)

也就是说,这个问题在 HTML 域而不是文本域中更好地表达:

$contents = <<<'EOS'
gg <a href="#">Anchor 1</a>, <a href="#" title="text">Anchor 2</a>
EOS;

$doc = new DOMDocument;
$doc->loadHTML($contents);
// find all anchors
foreach ($doc->getElementsByTagName('a') as $anchor) {
        if (!$anchor->hasAttribute('title')) {
                $anchor->setAttribute('title', $anchor->textContent);
        }
}

echo $doc->saveHTML();

要仅保存您感兴趣的节点,您将不得不使用这种构造:

foreach ($doc->getElementsByTagName('p')->item(0)->childNodes as $childNode) {
        echo $doc->saveHTML($childNode);
}
于 2013-07-15T13:25:20.270 回答