PHP捕获分隔符之间的子字符串

时间:2016-12-09 15:45:56

标签: php

这是我正在使用的代码:

$arr = "@media and (min-width: 768px){ .add{color: black;} } "
. "@media screen and (min-width: 480px) { body { background-color: " 
. "lightgreen; } } "
. "@media screen and (max-width: 480px) { div { background-color: "
. "lightgreen; } ul{color: red;} } ";

$keywords = array('@media', '}}');
$parts  = preg_split('/(' . implode('|', $keywords) . ')/', $arr
      , null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);

这是我的输出:

Array ( 
  [0] => "" 
  [1] => "@media" 
  [2] => "and (min-width: 768px){ .add{color: black;} }" 
  [3] => "@media" 
  [4] => "screen and (min-width: 480px) { body { background-color: lightgreen; } }"
  [5] => "@media" 
  [6] => "screen and (max-width: 480px) { div { background-color: lightgreen; } ul{color: red;} }" 
)

但是,我需要这个:

Array ( 
  [0] => 
  [1] => "@media and (min-width: 768px){ .add{color: black;} } "
  [2] => "@media screen and (min-width: 480px) { body { background-color: lightgreen; } } " 
  [3] => "@media screen and (max-width: 480px) { div { background-color: lightgreen; } ul{color: red;} } "
)

获得它的正确方法是什么?

EDITED: 两个分隔符是必要的,因为数组可能不会总是相同的。所以如果有这种情况:

  $arr = "@media and (min-width: 768px){ .add{color: black;} }"
   . " body{} @media screen and (min-width: 480px) { body "
   . "{ background-color: lightgreen; } } @media screen and "
   . "(max-width: 480px) { div { background-color: lightgreen; } "
   . "ul{color: red;} }";

所需的输出将是:

Array
(
    [0] => "@media and (min-width: 768px){ .add{color: black;} } "
    [1] => "body{} "
    [2] => "@media screen and (min-width: 480px) { body { background-color: lightgreen; } } "
    [3] => "@media screen and (max-width: 480px) { div { background-color: lightgreen; } ul{color: red;} } "
 )

1 个答案:

答案 0 :(得分:1)

有趣的问题!我提出了两个答案,第二个答案要好得多。

答案1:不干净,非常静电。

注意:此解决方案几乎只适用于OP提供的示例。要获得更好的解决方案,请查看 answer 2

我会想出一些更可调整的东西而不是static。现在,它的工作原理。 (Demo here

<?php
$arr = "@media and (min-width: 768px){ .add{color: black;} }"
. " body{} @media screen and (min-width: 480px) { body "
. "{ background-color: lightgreen; } } @media screen and "
. "(max-width: 480px) { div { background-color: lightgreen; } "
. "ul{color: red;} }";

$keywords = array("@media","} body");
$parts  = preg_split('/((?<='.implode('|',$keywords).')|(?='.implode('|',$keywords).'))/', trim($arr), null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$staticsize = count($parts);
for($i = 0; $i < $staticsize; $i++){
    if(!($i&1)){
        $next = $i + 1;
        if(strpos($parts[$i], '}') !== false){
            $parts[$i] = trim(str_replace("}","",$parts[$i]));
        }
        $parts[$next] = $parts[$i].$parts[$next];
        unset($parts[$i]);
    }
}
$parts = array_values($parts);
print_r($parts);
?>

这将为您提供所需的输出:

Array
(
    [0] => @media and (min-width: 768px){ .add{color: black;} 
    [1] => body{} 
    [2] => @media screen and (min-width: 480px) { body { background-color: lightgreen; } } 
    [3] => @media screen and (max-width: 480px) { div { background-color: lightgreen; } ul{color: red;} }
)

答案2:更多代码,更灵活。

现在事实是我已经提出了其他的东西,它是一个能够深入了解元素深度的函数,如果@media样式存在于第二度,那么将在那之内。这是函数:(Demo here

function split_depth($string){
    $keywords = array("{","}");
    $parts  = preg_split('/((?<='.implode('|',$keywords).')|(?='.implode('|',$keywords).'))/', trim($string), null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

    $noname = [];
    foreach(array_keys($parts) as $key){
        if(empty(trim($parts[$key]))){
            unset($parts[$key]);
        }
    }
    $parts = array_values($parts);
    foreach(array_keys($parts) as $key){

        switch(trim($parts[$key])){
            case "{":
                if(!array_key_exists($key, $noname)){
                    $noname[$key] = "open";
                }
            break;
            case "}":
                if(!array_key_exists($key, $noname)){
                    $noname[$key] = "close";
                }
            break;
        }
    }
    $open = 0;
    $close = 1;
    $cache = -1;
    $numberscache = 0;
    $sections = [];
    foreach(array_keys($noname) as $keyname){
        $name = $noname[$keyname];
        if($name == "open"){
            $open++;
        }else{
            if($open != 0){
                if($close == $open){
                    $c = ($cache) + (pow($open,2));
                    array_push($sections, array("open"  => $numberscache,"close" => $keyname));
                    $cache = $c + 1;
                    $numberscache = $keyname + 1;
                    $open = 0;
                    $close = 0;
                }   
            }else{
                echo "Syntax error in your CSS";
            }
            $close++;
        }
    }
    $parts = array_values($parts);
    $names = 0;
    $output = [];
    foreach($sections as $section){
        $name = "part".$names;
        $howmuch = ($section["close"] + 1) - $section["open"];
        $$name = trim(implode("",array_slice($parts,$section["open"],$howmuch)));
        array_push($output,$$name);
        $names++;
    }
    return $output;
}

此功能的用法:

$arr = "@media and (min-width: 768px){ .add{color: black;} }"
. " body{} @media screen and (min-width: 480px) { body "
. "{ background-color: lightgreen; } } @media screen and "
. "(max-width: 480px) { div { background-color: lightgreen; } "
. "ul{color: red;} }";
print_r(split_depth($arr));

就这么简单,它将输出完全相同,但现在它将适用于任何CSS。