微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

用于提取 css 规则和双大括号的正则表达式

如何解决用于提取 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}}

解决方法

你可以使用

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

参见regex demo详情

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

PHP demo

$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}}
)
,

如果格式始终相同,您还可以匹配从 2 个开头的卷曲到 2 个以 @ 开头的结尾卷曲,或者匹配单词字符后跟一个开头到结尾的卷曲。

(?s)@\w+\h+\w+\s*{[^{]*{.*?}\s*}|\w+{[^{}]+}
  • (?s) 内联修饰符,使点匹配换行符(如果在多行上)
  • @\w+\h+\w+\s* 匹配 @ 和 1+ 个单词字符、空格和再次单词字符
  • {[^{]*{ 匹配 { 然后匹配除 { 之外的可选字符,然后再次匹配 {
  • .*? 匹配尽可能少的字符
  • }\s*} 匹配 }},中间有可选的空白字符
  • |
  • \w+{[^{}]+} 匹配单词字符和来自 {...}

Regex demo

$re = '/(?s)@\w+\h+\w+\s*{[^{]*{.*?}\s*}|\w+{[^{}]+}/';
$str = '@keyframes animationName1{0%{opacity: 0}100%{opacity:1}}div{opacity:0}@keyframes animationName2{0%{opacity: 0}100%{opacity:1}}';
preg_match_all($re,$str,$matches);

print_r($matches[0]);

输出

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。