2013-07-07 132 views
2

我有一個變量($輸出)在PHP中,它包含將呈現給瀏覽器的所有html頁面,但我需要用數據替換所有圖像src:image以獲得lazyload js上班。替換身體標籤之間的所有圖像src只有

的要求是:

  • IMG SRC不具有相同的結構,我們有:

    < IMG SRC = 「img.jpg」 ALT = ''/ >

    < IMG ALT = 「文本」 SRC = 'img.gif' >

    < IMG類= 「MyClass的」 SRC = 「img.png」 ALT =」 '/ >

    ...等

  • 我只想以替換<體之間的圖像{可以有可選的文本} >和< /身體>

  • 不要替換img標籤<腳本{這裏可選的文本} >和< /腳本之間>

謝謝

+1

請問你能證明你迄今試過的東西嗎? – Jerry

+1

**不要使用正則表達式來解析HTML **。你不能用正則表達式可靠地解析HTML,你將面臨悲傷和挫折。只要HTML從你的期望改變,你的代碼就會被破壞。有關如何使用已經編寫,測試和調試的模塊正確解析HTML的示例,請參見http://htmlparsing.com/。 –

回答

0

很多人用正則表達式犯的錯誤是試圖寫一個巨大的正則表達式來完成一切。這種方式就是瘋狂。不僅不可能(取決於問題),而且會變得複雜,醜陋和脆弱。最好把事情分解成可管理的步驟。

你說你只想內<body>取代<img>標籤,但唯一的地方<img>標籤有效是內<body>,所以我會忽略這一點。如果您確實需要忽略<body>以外的<img>標籤,則可以將所有東西都包裝在另一個preg_replace_callback中,以便將<body>從輸入中取出。

因此,我採用的方法是使用兩個正則表達式:一個匹配輸入中<img>標記的所有實例,另一個替換alt屬性。要做到這一點,我用preg_replace_callback

$output = preg_replace_callback('/<img .*?>/', function($matches) { 
     return preg_replace('/\bsrc\s*=\s*[\'"](.*?)[\'"]/', 
      'data-image="$1"', $matches[0]); 
}, $input); 

注意在重複元字符*使用懶惰量詞?的:沒有這個,兩個連續<img>標籤將被視爲一個大的,這是我們要的不是什麼。在替換函數中,我查找src屬性並將其替換爲data-image屬性。

在此處,該解決方案將失敗:

  • 如果在報價分隔src屬性(<img src="what's_up_doc.jpg">)或反之亦然撇號。如果您需要解決這個問題,您必須有兩個不同的替換正則表達式,一個用於處理雙引號屬性,另一個用於處理單引號屬性。
  • 如果您的<img>標籤跨越多行。如果這是一個問題,在外部正則表達式中,您可以使用[^]而不是.來匹配所有內容,包括換行符。