【问题标题】:How to split CSS Code with PHP if is has sub brackets?如果有子括号,如何用 PHP 拆分 CSS 代码?
【发布时间】:2019-01-15 16:53:03
【问题描述】:

我尝试拆分存储在变量中的 CSS 代码。 但是,如果我有媒体查询或类似问题,我总是会遇到问题。

我不需要详细的规则,但是如果里面可以有括号,如何解决在括号处分割?

@media xyz { div { width: 100px; } a {color: blue;}}
#other-div { width: 200px; color: red;}

结果我只希望这是部分:

1: @mediy xzy

  1. div { 宽度:100px; } 一个 {颜色:蓝色;}

3: #other-div

4 宽度:200px;颜色:红色;

如果我只有 2 个结果(整个块),删除 cmets 或拆分将不是问题,我可以自己解决。但是我不能用括号解决这个问题,而不是它总是在下一个右括号处中断。

【问题讨论】:

  • 不要自己写这个,去寻找一个合适的现有 CSS 解析器吧。
  • 所有解析器都很复杂,因为我不需要获取所有规则,我只需要使用标识符即可。所有解析器都有自己的问题,我尝试了 csstidy(无法使用 webkit 框架等特殊功能)、sabberworm(内容有问题:'\231')等等。
  • “我遇到问题”是什么意思?分享您的代码和错误消息,我们会看看哪里出错了
  • 谢谢,csstidy 已被删除。使用 sabberworm,当我不做任何修改时:``` $parser = new Sabberworm\CSS\Parser($cssoutput); $oCss = $parser->parse(); $critical = $oCss->render(Sabberworm\CSS\OutputFormat::createCompact()); ``` 输出正在改变内容:'\421' 到 hyroglyphes。我只想要一开始的关键 css,所以我尝试删除规则 ``` foreach($oCss->getAllRuleSets() as $oRuleSet) { $oRuleSet->removeRule('content'); } ``` 那是行不通的,因为有hyroglyphes。我几乎尝试了每个字符集(至少输入是 utf-8 ..)
  • “所有的解析器都很复杂,因为我不需要获取所有规则,我只需要使用标识符即可。 ” - 那就尽情享受包含 #foo:before { content: "}"; } 等内容的 CSS 吧:-)

标签: php css parsing


【解决方案1】:

为了更好地了解这里是我的 Sabberworm 代码。

第一步:加载并保存:

$parser = new Sabberworm\CSS\Parser($cssoutput);
$oCss = $parser->parse();
$critical = $oCss->render(Sabberworm\CSS\OutputFormat::createCompact());

结果会出现如下问题:

fa-arrow-right:before{content:"ï¡";}.

好的,所以我尝试删除以下规则:

$parser = new Sabberworm\CSS\Parser($cssoutput);
$oCss = $parser->parse();
foreach($oCss->getAllRuleSets() as $oRuleSet) {
    $oRuleSet->removeRule('content');
}
$critical = $oCss->render(Sabberworm\CSS\OutputFormat::createCompact());

但这是删除的更多,我无法特别找到原因和方法,但 css 大约是之前的一半

我的主要部分(pq 是 phpQuery 的函数)导致错误(以及注释 removerule 部分)

$parser = new Sabberworm\CSS\Parser($cssoutput);
$oCss = $parser->parse();
foreach($oCss->getAllDeclarationBlocks() as $oBlock) {
    foreach($oBlock->getSelectors() as $oSelector) {
        echo "selektor: ".$oSelector->getSelector()."<br>";
        if(!pq($oSelector->getSelector())->length)
        {
            $oBlock->removeSelector($oSelector);
        }
    }

    if(count($oBlock->getSelectors()) === 0)
        $oCss->remove($oBlock);
}

$critical = $oCss->render(Sabberworm\CSS\OutputFormat::createCompact());

错误:未捕获 Sabberworm\CSS\Parsing\OutputException: Attempt to print declaration block with missing selector [line no: 20] in /var/www/vho...

【讨论】:

  • 图标字体问题我只是通过更改之前的字符来解决:$cssoutput = str_replace('\f','###f',$cssoutput); 和之后的$critical = str_replace('###f','\f',$critical);,但是直到现在我才弄清楚块中缺少选择器的错误问题。跨度>
【解决方案2】:

你可以这样做:

<?php

$css = "@media xyz { div { width: 100px; } a {color: blue;}}
#other-div { width: 200px; color: red;}";

// split by line break
$lines = preg_split('/[\r\n]+/', $css);

$parts = [];
foreach ($lines as $line) {

  // parse everything that's not "{" unit first "{" and the rest until last "}"
  preg_match_all('/^([^{]+)\{(.+)\}/', $line, $matches);

  // remove total result
  array_shift($matches);

  // remove second array level + trim
  $matches = array_map(function($match) {
    $match = array_shift($match);
    return trim($match);
  }, $matches);

  // add to parts array
  $parts = array_merge($parts, $matches);
}

var_dump($parts);
//array(4) {
//  [0] =>
//  string(10) "@media xyz"
//  [1] =>
//  string(38) "div { width: 100px; } a {color: blue;}"
//  [2] =>
//  string(10) "#other-div"
//  [3] =>
//  string(25) "width: 200px; color: red;"
//}

【讨论】:

  • 谢谢,也许是我的错误:只有当我在一行中都有规则时才有效,但这只是一个例子。我需要检查整个字符串。
猜你喜欢
  • 2016-03-31
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 2022-11-29
相关资源
最近更新 更多