如何解决用于提取 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+{[^{}]+}
匹配单词字符和来自{...}
$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 举报,一经查实,本站将立刻删除。