【问题标题】:regex for extracting css rules and double curly brackets用于提取 css 规则和双花括号的正则表达式
【发布时间】:2021-09-22 20:23:58
【问题描述】:

目前我正在使用分离 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}}

【问题讨论】:

  • 没有对您的previous question 的反馈?
  • @Thefourthbird 感谢您的 cmets。我赞成 Tims 的评论,因为它解决了我在上一个问题中遇到的问题。起初我想过滤掉双括号规则并得出结论,我可以调整规则以提取所有 css 规则,而不是过滤掉那些不适用于它的规则。

标签: php css regex


【解决方案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}}
)

【讨论】:

    【解决方案2】:

    你可以使用

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

    请参阅regex demo详情

    • ([^{}]+) - 捕获组 1:除 {} 之外的一个或多个字符
    • ({((?:[^{}]++|(\g&lt;2&gt;))*)}) - 第 2 组:
      • { - 一个 { 字符
      • ((?:[^{}]++|(\g&lt;2&gt;))*) - 第 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}}
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      相关资源
      最近更新 更多