2011-01-31 110 views
1

我正在爲我的客戶端編寫一個應用程序,該應用程序使用所見即所得來允許員工修改帶有某些變量的信件模板,這些變量被解析爲用於該信件寫入的客戶的信息。使用正則表達式遞歸HTML標籤的內容

所見即所得生成的HTML我保存到SQL服務器數據庫。然後我使用一個PHP類來生成帶有模板文本的PDF文檔。

這是我的問題。 PDF生成類可以翻譯b,u,i HTML標籤。而已。除了我還需要翻譯blockquote之外,這大部分都是可以的。我認爲最好的解決方案是編寫一個正則表達式語句來獲取每個blockquote HTML塊的內容,並用五個空格替換塊中的每一行。訣竅是一些blockquotes可能包含嵌套塊引用(雙縮進,什麼不是)

但不幸的是,我從來沒有太熟練的正則表達式,我花了最後1.5小時試驗不同的模式,並沒有任何工作。

這裏是gotchyas:

  • 字符串可能會或可能不會包含塊引用塊
  • 字符串可以包含多個引用文字
  • 字符串可能包含引用文字塊的任何級別的嵌套
  • 我們可以依賴正確形成的HTML

樣本輸入字符串將b Ë看起來像這樣的事情:

Dear Charlie,<br><br>We are contacting you because blah blah blah blah.<br><br><br>To login, please use this information:<blockquote>Username: someUsername<br>Password: somePassword</blockquote><br><br>Thank you. 

爲了簡單的解決方案,我需要用5個空格,然後\ n換行符替換每塊引用內的每個HTML休息。

+1

似乎更正確的修改PDF創建者比米老鼠周圍的RegEx問題。這是一個你正在使用的封閉源庫,還是可以修改的東西? – 2011-01-31 16:45:10

+0

@Brad這是這個課程 - > http://www.ros.co.nz/pdf/ < - 我最初用它來爲客戶生成郵件標籤,但我也將它擴展爲爲客戶生成歡迎信。 – WhiskeyTangoFoxtrot 2011-01-31 16:48:42

+0

你確實實現了「blockquote indent」!==「intent 5行開頭的空格」對吧? – timdream 2011-01-31 16:54:00

回答

3
~<blockquote>((?:[^<]*+(?:(?!<blockquote>)|(?R))*+)*+)</blockquote>~ 

您需要遞歸運行這個表達式使用preg_replace_callback

const REGEX_BLOCKQUOTE = '~<blockquote>((?:[^<]*+(?:(?!<blockquote>)|(?R))*+)*+)</blockquote>~'; 
function blockquoteCallback($matches) { 
    return doIndent(preg_replace_callback(REGEX_BLOCKQUOTE, __FUNCTION__, $matches[1])); 
} 

$output = preg_replace_callback(REGEX_BLOCKQUOTE, 'blockQuoteCallback', $input); 

我正則表達式假設,那也不會有對塊引用或其他任何地方的任何屬性。

1

正則表達式有theory behind them,即使現今的常規expresison引擎提供可以提供一個「類型 - (PS我將離開「使用DOM解析器」評論別人。) 2.5'級的語言,有些東西還是不可行的。在你的情況下,嵌套是不容易實現的。 一個簡單的方法的方式來解釋這一點,是說正則表達式不能保持一個計數.. 即它們不能算嵌套層次......

你需要的是一個有限的CFG(中paren-counting types).. 您需要以某種方式保留一個計數..可以是堆棧或樹...