2013-07-15 51 views
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個title屬性。爲什麼這不按預期工作?我該如何解決它?

+0

使用html dom解析器來執行此操作,而不是正則表達式 – DevZer0

+0

lookahead斷言''!'不掩蓋'[^ <] *'佔位符。這只是你放置它的地方。 – mario

+0

[添加一個nofollow屬性來鏈接,如果沒有使用PHP標題標記](http://stackoverflow.com/questions/6160645/add-a-nofollow-attribute-to-link-if-no-title-使用php) – mario

回答

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); 
} 
+0

這很好,thx,但DOMDocument添加doctype和html標籤,但我需要修改partials html塊 – gvozd1989

+0

@ gvozd1989我也給出了一個解決方案。 –

+0

謝謝!是工作。 – gvozd1989