2012-11-19 98 views
0

我想將第二個h2標記替換爲h3,我希望有人可以用替換正則表達式或者preg_split來幫助我 - 我不太確定。只替換第二個html標記

例如,這樣的:

<h2>My text one</h2> 
<h2>My text two</h2> 
text … 
<h2>My text three</h2> 

應該成爲這樣的:

<h2>My text one</h2> 
<h3>My text two</h3> 
text … 
<h2>My text three</h2> 
+3

你爲什麼用PHP替換html元素我認爲這是問題。你確定你不是指Javascript嗎? – thatidiotguy

+0

它們是否像你的例子中的新行分開? – sidyll

+0

您應該使用DOM解析器。 – jeroen

回答

2

我與其他評論同意,應通過DOM解析器來完成。但是,儘管如此,這仍然是一個可行的php解決方案

<?php 
    // Fill $str with the html; 

    preg_replace("/[h]{1}[2]/i", "h3", $str); 
?> 

<?php 
    // Fill $str with the html; 

    str_replace("h2", "h3", $str);  
?> 

這應該只是罰款。將$ matches參數添加到preg_replace中還會跟蹤所做更改的數量。 現在,使用一個循環你可以控制需要更換哪個元素,但是,如上述寫入的功能將檢測h2的所有 OCCURENCES。

而且,你能夠換出的數量,以使更實用的功能與它我已經過於複雜的正則表達式。只要使用「/(h2)/我」也可以做到這一點。

所以,你的代碼應該實現以正確的方式循環,以防止更換所有的標籤,如果功能將要處理只是h2的,還是應更靈活,你應該決定。

作爲最後的一句話,str_replace函數比preg_replace函數快,所以如果這是你需要做的唯一的編輯,我會建議str_replace函數。

2

您可以輕鬆地做到這一點與的Javascript,是否真的需要用PHP?

獲取第二<h2>

$text = $("h2:eq(1)").html(); 

摧毀它。

$("h2:eq(1)").remove(); 

$("h2:eq(0)").after("<h3>" + $text + "</h3>"); 
+0

-1,這就是javascript。 – mowwwalker

+1

OP沒有說它不能是JavaScript。 – BernaMariano

+1

服務器端和客戶端之間有很大的區別。他標記了PHP,詢問了關於PHP的內容,並且從未提及過JavaScript。儘管如此,他對於他究竟在做什麼以及他正在使用什麼都非常模糊,所以,第二,儘管如此,他可能意味着javascript。 – mowwwalker

1

你並不需要使用服務器端的HTML解析器該第一<h2>後建立一個<h3>,與$text,那將是完全矯枉過正海事組織。下面是一個很明顯可以被某些HTML結構破壞的例子,但是對於大多數標記來說,它不會有什麼問題 - 並且會比服務器端的HTML分析器更加優化。

$html = ' 
<h2>My text one</h2> 
<h2>My text two</h2> 
text ... 
<h2>My text three</h2> 
'; 

preg_match_all

/// the following preg match will find all <h2> mark-up, even if 
/// the content of the h2 splits over new lines - due to the `s` switch 
/// It is a non-greedy match too - thanks to the `.+?` so it shouldn't 
/// have problems with spanning over more than one h2 tag. It will only 
/// really break down if you have a h2 as a descendant of a h2 - which 
/// would be illegal html - or if you have a `>` in one of your h2's 
/// attributes i.e. <h2 title="this>will break">Text</h2> which again 
/// is illegal as they should be encoded. 

preg_match_all(
    '#(<)h2([^>]*>.+?</)h2(>)#is', 
    $html, 
    $matches, 
    PREG_OFFSET_CAPTURE|PREG_SET_ORDER 
); 

替代和重建

/// Because you wanted to only replace the 2nd item use the following. 
/// You could however make this code as general or as specific as you wanted. 
/// The following works because the surrounding content for the found 
/// $matches was stored using the grouping brackets in the regular 
/// expression. This means you could easily change the regexp, and the 
/// following code would still work. 

/// to get a better understanding of what is going on it would be best 
/// to `echo '<xmp>';print_r($matches);echo '/<xmp>';` 

if (isset($matches[1][0])) { 
    $html = substr($html, 0, $matches[1][0][1]) . 
      $matches[1][1][0] . 'h3' . 
      $matches[1][2][0] . 'h3' . 
      $matches[1][3][0] . 
      substr($html, $matches[1][0][1] + strlen($matches[1][0][0])); 
} 

我不知道爲什麼許多人都聲稱使用客戶端JavaScript這種變化,PHP代表它被設計爲預處理超文本。 OP僅提到了PHP函數,並用PHP標記了這篇文章,所以沒有任何東西導向客戶端。

儘管客戶端可以並且應該儘可能地減少來自服務器端的處理,但這不應該推薦用於核心結構標籤,比如標題 - 屏幕閱讀器和搜索引擎機器人會依賴這種標籤。最好的客戶端JavaScript應該用來增強用戶的體驗。如果您使用它來嚴格增強網站的功能,最好確保您的enitre用戶羣支持它。

但是,如果你們中有人提到Node.jsJSDOM,我會非常高興地同意。

+0

這還有待觀察。瀏覽器不需要爲它做很多額外的工作。它已經有了dom-tree。要指出的是,請求是更改硬編碼的html。在我看來,這應該儘可能地留給客戶。 – Digitalis

+0

@Digitalis對不起,我不包括客戶端在我的答案,因爲它沒有要求的OP。關於改變標題標籤這不會是一個好主意,從JS做關於搜索引擎優化。 – Pebbl

+0

爲什麼在客戶端改變它會對SEO產生負面影響?另外,沒有傷害。你提供的例子也做它需要做的事情,只要它有生產力,我總是在討論。 – Digitalis