我希望在html文档中匹配并捕获所有现有(如果有) <style...</style>
块和一个 <body..</body>
块内部。
我觉得这很简单,但我碰到了一些奇怪的东西。
这是我对整个正则表达式的猜测:
/(<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
所以,我猜错误是子模式后面的*和+之间的差异。为什么?我该如何解决这个问题?
谢谢!
答案 0 :(得分: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>
块全部相邻且仅由空格分隔。你能明白为什么使用正则表达式不是一个好主意吗?