2011-10-21 93 views
0

蔭試圖替換&符號使用的preg_replace我的HTML sidewide,但問題是,它打破聯JavaScript & &或JavaScript網址樣?頁=測試& ID = 1PHP的preg_replace正則表達式前瞻

現在我有這個代碼,它的工作原理

$amp_replace = array(); 
$amp_replace[0] = '/(?<=\s)&(?!&)(?!#?[a-z0-9]+;)/'; 
$amp_replace[1] = '/(?<!&)&(?=\s)/'; 
$skin = preg_replace($amp_replace, '&amp;', $skin); 

當左側或右側空間替換時,替換&符號。不要在連續2個符號(對於javascript)或者通過html實體跟隨時進行替換。

但我在這裏找到了一些不需要的邏輯。它也不會取代&符號,如果它的測試&測試。

由於我沒有正則表達式的專家,這讓我有一段時間了,所以我想我再次尋求幫助。

如果不在JavaScript腳本標記中,簡單地替換所有&符號會更好嗎?我試過,但已經沒有真正的成功

有誰知道我該如何歸檔? 謝謝

+0

怎麼這些'&'那裏擺在首位?你不應該解決這個問題嗎? –

+0

用戶提交的內容。我知道我可以通過寫入每個php文件來修復它,以修復&符輸出。但在這種特殊情況下,我不需要那樣。由於我的pp編碼變得足夠大,我寧願爲此擁有一個全局聲明。查看我所有的html,如果不在腳本標記中,則替換 – Basti

回答

0

爲什麼不喜歡簡單的東西:

$html = preg_replace('/([^&])&([^&])/', '$1&amp;$2', $html);

如果你想避免更換Javascript中所有的&符號,加超前/落後於script標籤,或先在script標籤拆分文檔,並且只對非腳本部分運行替換。

$html = preg_split('/<\/?script>/', $html); 
foreach ($html as $k => $v) { 
    if ($piece[0] == "<") { 
    $html[$k] = preg_replace('/([^&])&([^&])/', '$1&amp;$2', $v); 
    } else { 
    $html[$k] = "<script>" . $html[$k] . "</script>"; 
} 

如果您的腳本標記具有屬性,這將需要一些修改。

如果您正在清理用戶內容,那麼使用已經可用的工具可能會更好。見HTML Purifier

+0

$ skin var是我的解析html,所以我通過我的洞html來查看,這在我的情況下不起作用。因爲我上面的作品,但我希望它simpliere,就像替換所有&如果不在腳本標記。我知道我可以簡單地在我的每個功能中進行替換,但我寧願只寫一次 – Basti

+0

也嘗試過使用腳本標記,但它看起來像我從來沒有得到它的權利,無論是錯誤還是它不替換 – Basti

+0

將嘗試分裂的方法,謝謝:) – Basti

1

如果你只是想在內容轉換「&」,避免標籤(即:屬性值)
,避免腳本塊,像下面將大部分occurances工作。
但是,應該注意的是,屬性值也應該被轉換。
這樣做需要更多的工作。

工作樣本http://www.ideone.com/9MhCq

<?php 

$html=<<<EOD 
<some &ta&g> S&P &&more; and &some; <more> &notme; 
    && &#209; &#xa92F; 
<script flavor?> 
    val && this & this 
</script> 
& 
EOD; 

$rxent = '(?:&(?:[A-Za-z_:][\w:.-]*|\#(?:[0-9]+|x[0-9a-fA-F]+));)'; 

$rxtag = 
'< 
(?: 
    \?php\s+.*?\? 
    | (?: 
     (?: 
      (?:script|style)\s* 
     | (?:script|style)\s+(?:".*?"|\'.*?\'|[^>]*?)+\s* 
     )> .*? </(?:script|style)\s* 
    ) 
    | (?: 
     /?[A-Za-z_:][\w:.-]*\s*/? 
     | [A-Za-z_:][\w:.-]*\s+(?:".*?"|\'.*?\'|[^>]*?)+\s*/? 
     | !(?:DOCTYPE.*?|--.*?--) 
    ) 
) 
> 
'; 

$rxmain = "~(?xs:((?:$rxtag)+) | ((?!$rxent)&))~"; 


print "$html\n\n"; 

$html = preg_replace_callback($rxmain, 'fixamp_cb', $html); 

print "$html\n"; 

function fixamp_cb($matches) { 
    # Return tags and script blocks unchanged. 
    if (isset($matches[1]) && $matches[1]) 
     return $matches[1]; 
    return '&amp;'; 
} 

?>