如何用正则处理CSS解析中的内部大括号问题?
解决CSS嵌套
{}场景下的正则解析问题 你的问题根源在于原始正则表达式里的[^}]+会在遇到第一个}就停止匹配,没法处理@keyframes这类内部包含嵌套{}的CSS规则。要解决这个问题,我们可以利用PHP PCRE支持的递归匹配来处理平衡的{}结构。
修正后的正则表达式与代码示例
这里是可以正确解析嵌套{}的轻量化正则方案:
$css = 'table { border-collapse: collapse; border-spacing: 0 } @keyframes blinking { from { background: #f4a83d } to { background: rgba(244, 168, 61, 0) } }'; // 使用递归匹配处理嵌套的{}结构 preg_match_all('/([^{]+)\s*\{\s*((?:[^{}]|(?R))*)\s*}/', $css, $matches); // 查看解析结果 print_r($matches[1]); // 捕获到的选择器/规则前缀数组 print_r($matches[2]); // 捕获到的对应规则内容数组
正则表达式核心逻辑拆解
让我们逐个部分解释这个正则的作用:
([^{]+):捕获CSS选择器(或@keyframes这类特殊规则的前缀),匹配所有非{的字符\s*\{\s*:匹配{符号以及前后可能存在的空白字符((?:[^{}]|(?R))*):这是处理嵌套的核心部分:[^{}]:匹配普通的非{}字符(?R):递归调用整个正则表达式,用来识别并匹配嵌套的{}结构- 整个非捕获组会循环匹配,直到遇到与最外层
{对应的闭合}
\s*}:匹配}符号以及前后可能存在的空白字符
预期解析结果
运行上述代码后,你会得到符合预期的两组结果:
- 选择器数组:
Array ( [0] => table [1] => @keyframes blinking ) - 规则内容数组:
Array ( [0] => border-collapse: collapse; border-spacing: 0 [1] => from { background: #f4a83d } to { background: rgba(244, 168, 61, 0) } )
适用场景与小提醒
- 这个方案针对你“仅捕获选择器和规则”的轻量化需求设计,能覆盖绝大多数常规CSS场景。
- 如果你的CSS中存在字符串形式的
{/}(比如content: "{open}"),正则可能会误判;如果需要处理这类边缘情况,可以额外添加逻辑排除字符串内的符号,但对于普通场景,当前方案已经足够简洁实用。
内容的提问来源于stack exchange,提问作者Googlebot
相关产品推荐
相关产品推荐

