2011-01-31 108 views
0

我想匹配,趕上所有現有的(如果有的話)<style...</style>塊和一個<body..</body>塊的HTML文檔裏面。 我認爲這很簡單,但我碰到奇怪的東西。 這是我整個正則表達式的猜測:PCRE(php)正則表達式,具有+匹配的子模式和*不具有?

/(<style[\s\S]+<\/style>)*[\s\S]*<body.*>([\s\S]+)<\/body>/i 

它導致成什麼。所以,我除了把它弄壞了這些部件的工作:

/(<body.*>([\s\S]+)<\/body>)/i 
/(<style[\s\S]+<\/style>)/i 

而且最奇怪所有這些第一線的工作也,而第二名的成績空!

/(<style[\s\S]+<\/style>)+/i 
/(<style[\s\S]+<\/style>)*/i 

所以,我想誤差*和+子模式後之間的差異。爲什麼?我該如何解決這個問題?

謝謝!

回答

1

你有四個方面的問題:

第一和第二,你使用正則表達式來解析HTML。第三,你太匹配了:你至少需要讓一些量詞懶惰,我。即使用.*?,[\s\S]*?等,或者你的正則表達式會匹配所有行到文件末尾的所有內容,然後只根據需要回溯,找到最後一個可能的匹配標記。第四,通過在重複組內重複組,你已經爲災難性回溯設置了自己,這兩個組都有很多方法來匹配相同的文本。

當我明白你的問題,你想匹配一切從第一<style>標籤到最後</body>和捕獲所有<style>標籤的內容和<body>標籤的內容。對?然後嘗試

/(<style[\s\S]+<\/style>)[\s\S]*?<body.*?>([\s\S]+)<\/body>/i 

要單獨捕獲每個<style>塊,你可以嘗試,最多的四種可能<style>塊:

/(<style[\s\S]+?<\/style>)?\s*(<style[\s\S]+?<\/style>)?\s*(<style[\s\S]+?<\/style>)?\s*(<style[\s\S]+?<\/style>)?\s*<body.*?>([\s\S]+)<\/body>/i 

如果<style>塊都相鄰,只用空格隔開。你能看出爲什麼使用正則表達式不是一個好主意嗎?

+0

感謝您改善錯誤。這是一個開始。 :-S – 2011-01-31 12:59:31