使用正则表达式解析 css 背景 url 和选择器

Parsing css background url and selector using regex

我正在尝试更改具有内联样式的 HTML 页面,我想制作一个捕获背景 url 和选择器的正则表达式,示例:

<div>some html here</div>
<style>#some-selector {
  padding-top: 408px;
}
#some-selector .bg {
  background-image: url(www.some-url.com/some-image.jpg);
}
#some-selector {
  background-position: 43% 97%;
}

我这里要抓取的是#some-selector .bgwww.some-url.com/some-image.jpg,切记HTML页面大,表达要快

我想出了这个 expr <style[\s\S]*?[>}\/\n](.*){[\s\S]*?background.*?url\((.*?)\) 但它不能正常工作,我知道我第一个 [\s\S] 应该是贪婪的但是当我删除 ? 它会导致灾难性的回溯 <style[\s\S]*[>}\/\n](.*){[\s\S]*?background.*?url\((.*?)\) 它确实适用于小字符串,但在整个页面上它会导致灾难性的回溯,我已经使用 regex101 对其进行了测试。

感谢任何帮助

编辑:这是一个示例 https://regex101.com/r/ZMxOSz/1

更新
仔细研究后,我提供了 2 个解决方案,可以在相对程度上缓解回溯问题。
在查看它们之前,我想指出只有很少的分隔符与 CSS 语法相关。
此外,它与定义 CSS 语法的允许字符的顺序和内容更相关。

回溯的治疗方法是将正则表达式引擎限制在允许的范围内
要匹配并具有战略位置的字符。
如果您在此处查看 CSS 规范 -> https://www.w3.org/TR/CSS21/syndata.html
您会注意到它完全由正则表达式定义。
这表明 CSS 解析器完全由正则表达式的切碎版本构建。

然而,虽然将其放入
中是一项有趣的练习 所有包含正则表达式,我会拒绝这个挑战,因为有
对我来说没什么。

相反,我提供了这 2 个根据您的要求量身定制的正则表达式。

第一个:

  • 仅匹配 <style> 元素中的第一个 url()

<style[^>]*?>(?:[^{}:]*{[^{}]*?:[^{}()]*?})*?(?:([^{}:]*){[^{}]*?:\s*url\s*\(\s*([^{}()]*?)\s*\)\s*})

见 -> https://regex101.com/r/2SNIks/1


第二个:

  • 匹配所有 url() 块与 <style> 元素

(?:<style[^>]*?>|(?!^)\G)(?:(?:(?!</style)[^{}:])*{[^{}]*?:[^{}()]*?})*?(?:([^{}:]*){[^{}]*?:\s*url\s*\(\s*([^{}()]*?)\s*\)\s*})

见 -> https://regex101.com/r/d8q6LH/1


对于两个正则表达式,

  • 选择器在组 1 中
  • url 在组 2