首页 > 解决方案 > 用于提取 css 规则和双花括号的正则表达式

问题描述

目前我正在使用分离css规则

preg_match_all( '/(?ims)([a-z0-9s,.:()#_\-@>*]+){([^}]*)}/', $content, $arr);

它工作正常。但是,如果我有这样的双花括号

@keyframes animationName1{0%{opacity: 0}100%{opacity:1}}div{opacity:0}@keyframes animationName2{0%{opacity: 0}100%{opacity:1}}

由于其中的大括号,此正则表达式不会提取所有动画规则。我需要支持调整所述规则以查看外部括号并忽略内部括号。

这些应该是结果:

1: @keyframes animationName1{0%{opacity: 0}100%{opacity:1}}
2: div{opacity:0} 
3: @keyframes animationName2{0%{opacity: 0}100%{opacity:1}}

标签: phpcssregex

解决方案


您可以使用

([^{}]+)({((?:[^{}]++|(\g<2>))*)})

请参阅正则表达式演示详情

  • ([^{}]+)- 捕获组 1:一个或多个除{and之外的字符}
  • ({((?:[^{}]++|(\g<2>))*)}) - 第 2 组:
    • {- 一个{字符
    • ((?:[^{}]++|(\g<2>))*){- 第 3 组:除和或第 2 组模式之外的任何一个或多个字符出现零次或多次}(递归)
    • }- 一个}字符

查看PHP 演示

$text = "@keyframes animationName1{0%{opacity: 0}100%{opacity:1}}div{opacity:0}@keyframes animationName2{0%{opacity: 0}100%{opacity:1}}";
$rx = '~([^{}]+)({(?:[^{}]++|(\g<2>))*})~';
if (preg_match_all($rx, $text, $m)) {
    print_r($m[0]);
}

输出:

Array
(
    [0] => @keyframes animationName1{0%{opacity: 0}100%{opacity:1}}
    [1] => div{opacity:0}
    [2] => @keyframes animationName2{0%{opacity: 0}100%{opacity:1}}
)

推荐阅读