regex - 使用正则表达式解析 css 背景 url 和选择器
问题描述
我正在尝试更改具有内联样式的 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 .bg
and www.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 个正则表达式。
第一个:
- 仅匹配元素中的第一个
url()
块<style>
<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 组中
- 该网址在第 2 组中
推荐阅读
- graalvm - 如何判断您的 Java 程序是否在 GraalVM AOT 上下文中运行?
- java - 使用 Jmeter 连接到 MQ,并提供返回地址
- python - 如何将变量注入到 Django 模板的上下文中,类似于内置“url”标签的“as”参数?
- ios - 如何在 Swift 中将 UIColor 转换为 3/4/6/8 位十六进制字符串?
- gradle - 只为一个子项目调用 Gradle 任务
- java - Java Android If Else Break 出现问题故障排除
- python - Scipy welch 和 MATLAB pwelch 不提供相同的答案
- java - Springboot 测试未返回预期结果
- c# - 如何让我的角色以第三人称在镜头周围跑来跑去?
- javascript - 似乎无法将我的 CSS 和 JS/Jquery 文件集成到我的 HTML 中