【发布时间】:2016-08-22 23:33:14
【问题描述】:
我正在寻找可以可靠地匹配媒体查询及其内容的正则表达式(在 PHP PCRE 中),包括媒体查询正文为空的有点奇怪的情况。源文本可能是:
@media only screen {
p {
color:red;
}
}
@media only screen and (max-width: 596px) {
p {
color:blue;
}
img {
max-width: 200px;
}
}
@media only screen {
}
img {
display: block;
}
@media only screen and (max-width: 240px) {
p {
color:green;
}
}
p {
font-weight: normal;
}
我想将每个媒体查询及其 CSS 主体捕获为子模式,所以我最终会得到一个 PHP 数组,如下所示:
[['@media only screen {
p {
color:red;
}
}','p {
color:red;
}'],...]
关键是这需要是递归或子例程模式才能平衡大括号。空查询足以混淆this question中的模式,因为它无法区分css规则的结尾和空媒体查询的结尾:
/@media[^{]+\{([\s\S]+?\})\s*\}/
我一直在尝试使用this article 中的建议来创建(b(?:m|(?1))*e) 形式的模式,但未能成功,其中b 是构造的开始,m 是中间可能发生的构造,e 是最后可能发生的,它们都不能匹配相同的东西。
所以,b应该是@media[^{]+\{,e应该是\},而m需要消耗CSS规则,也许([^{]+?\{[^}]*?\s*\}),给我:
/(@media[^{]+\{(?:([^{]+?\{[^}]*?\}\s*)*|(?1))*\})/s
但是,这不起作用,所以我有点迷茫。谁能提出一个有效的模式?
我已经设置了一个正则表达式测试here。
或者,非正则表达式解析器可能会更好。
请注意,我一般不会尝试验证或匹配 CSS 选择器(不是正则表达式的工作),只是获取查询的内容及其正文。
更新添加了更多示例内容,解释了我想要得到的内容。
【问题讨论】:
-
不,它可以是任何有效的媒体查询。
-
@WiktorStribiżew 应该是
[^{}]++还是[^{}]+? -
@rock321987:一个常用的非占有量词在这里也能起作用,任何一个都可以。
-
非常接近,谢谢。我希望捕获的组略有不同,我已经更新了问题以表明这一点。
标签: php css regex recursion pcre