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 番目のリンクには、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 に答える