1

我正在使用 str_replace 清理 CSS 输出,但需要忽略具有定义的开始和结束的某些字符串块。

忽略以下开头的任何内容:

@media blah(this can be any value) {

要忽略的内容:

  .class {
    property: value;
  }

并以:

}/*ends*/

并在该块之外执行 str_replace :

.otherclass {property:value;}

PHP:

$output = str_replace("{", "{\n", $output);
$output = str_replace("}", "}\n", $output);

原因是 @media 块需要适当的缩进,该缩进已经正确格式化,并且不应被 str_replace 触及,它简单地返回可读行:

 .otherclass {
  property:value;
  }

你会用 PHP 怎么说?

谢谢

4

3 回答 3

1

我还认为正则表达式是可行的方法,因为它们为您提供了更大的灵活性。

我想天真的解决方案是首先从输出源中获取所有这些事件,然后在剩余代码上使用 str_replace,然后将其放回去。也可以尝试逐行遍历代码并且只运行 str_replace

同样,您最好的机会是使用正则表达式。您正在寻找的似乎是 preg_replace,告诉它不匹配 @media 之前的任何内容

参考:

于 2012-04-24T04:39:08.593 回答
1

正则表达式不能计数,因此它们通常不适合解析(这就是您正在做的事情)。即,除非您可以限制输入格式超过全套有效 CSS,否则您可能会发现某些情况无法按预期工作。

您还可以尝试完全解析 CSS 并使用规则遍历生成的 CSS 树,以指定如何输出数据。这里显然有一个 CSS 解析器库:

http://www.phpclasses.org/package/1289-PHP-CSS-parser-class.html

于 2012-04-24T05:36:20.447 回答
1
$string = 
"@media blah(this can be any value) {
.class {
    property: value;
  }
}/*ends*/

.otherclass {property:value;}

.otherclass {property:value;}

@media blah(this can be any value) {
.class {
    property: value;
  }
}/*ends*/

.otherclass {property:value;}

.otherclass {property:value;}";

$arr = explode("\r", $string);

$ignore_block = false;
for ($i = 0; $i < count($arr); $i++)
{
    if (strstr($arr[$i], '@media'))
        $ignore_block = true;
    elseif (strstr($arr[$i-1], '/*ends*/'))
        $ignore_block = false;

    if ($ignore_block == false)
    {
        $arr[$i] = str_replace("{", "{\n\t", $arr[$i]);
        $arr[$i] = str_replace("}", "\n}\n", $arr[$i]);
    }
}
file_put_contents("test.txt", implode("\n", $arr));

正则表达式不起作用,因为lookbehind 不允许可变长度。尝试遍历文件。

于 2012-04-24T05:51:45.893 回答