删除依赖于RegEx类的CSS规则

时间:2017-10-05 11:16:57

标签: php css regex sass

说明:

我对RegEx相当新,所以请耐心等待。我们有一个客户端拥有一个非常大的CSS文件。总计27k行 - 大约20k行是纯CSS,以下是用SCSS编写的。我试图减少它,尽管使用超过规定的时间来处理这个问题,我发现它非常有趣 - 所以我写了一个小PHP脚本来为我做这个!不幸的是,由于RegEx有点麻烦,它并不完全存在。

上下文

remove.txt - 包含选择器的文本文件,逐行显示在我们的网站上是多余的,可以删除。 main.scss - 大SASS文件。 PHP脚本 - 基本上逐行读取remove.txt文件,在main.scss文件中找到选择器,并在每个选择器之前添加一个“UNUSED”字符串,这样我就可以逐行删除并删除规则。

问题

因此,麻烦的主要原因是因为我们必须在CSS规则的开头和结尾处考虑很多事件。例如 -

.foo-bar的示例场景(粗体表示应匹配的内容) -

.foo-bar {}

.foo-bar ,。bar-foo {}

.foo-bar .bar-foo {}

.boo-far, .foo-bar {}

.foo-bar ,。bar-foo {}

.bar-foo.foo-bar {}

PHP脚本

<?php 

$unused = 'main.scss';
if ($file = fopen("remove.txt", "r")) {

    // Stop an endless loop if file doesn't exist
    if (!$file) {
        die('plz no loops');
    }

    // Begin looping through redundant selectors line by line 
    while(!feof($file)) {

        $line = trim(fgets($file));

        // Apply the regex to the selector
        $line = $line.'([\s\S][^}]*})';

        // Apply the global operators
        $line = '/^'.$line.'/m';

        // Echo the output for reference and debugging
        echo ('<p>'.$line.'</p>');

        // Find the rule, append it with UNUSED at the start
        $dothings = preg_replace($line,'UNUSED $0',file_get_contents($unused), 1);

    }
    fclose($file);
} else {
    echo ('<p>failed</p>');
}
?>

正则表达式

从上面你可以收集我的RegEx -

/^REDUNDANTRULE([\s\S][^}]*})/m

目前,处理媒体查询中通常会出现的缩进以及应用于同一规则的进行选择器时,现在很难处理。

由此我尝试添加到开头(以适应空格以及何时在较长版本的选择器中使用选择器) -

^[0a-zA-Z\s]

并将此添加到最后(以容纳用于分隔选择器的逗号)

\,

任何RegEx / PHP向导都能指出我正确的方向吗?谢谢你的阅读!

感谢@ctwheels提供了精彩解释的答案。我遇到了一些其他问题,一个是在收到的冗余规则中没有被转义的完全停止。我现在更新了我的脚本以逃避它们,然后再进行查找替换,如下所示。这是我最新的工作脚本 -

<?php 

$unused = 'main.scss';
if ($file = fopen("remove.txt", "r")) {
    if (!$file) {
        die('plz no loops');
    }
    while(!feof($file)) {

        $line = trim(fgets($file));
        if( strpos( $line, '.' ) !== false ) {
            echo ". found in $line, escaping characters";
            $line = str_replace('.', '\.', $line);
        }
        $line = '/(?:^|,\s*)\K('.$line.')(?=\s*(?:,|{))/m';
        echo ('<p>'.$line.'</p>');
        var_dump(preg_match_all($line, file_get_contents($unused)));
        $dothings = preg_replace($line,'UNUSED $0',file_get_contents($unused), 1);
        var_dump(
            file_put_contents($unused,
                $dothings
            )
        );
    }
    fclose($file);
} else {
    echo ('<p>failed</p>');
}
?>

1 个答案:

答案 0 :(得分:1)

答案

根据您提供的示例,以下正则表达式将起作用,但是,它不适用于所有CSS规则。如果添加更多案例,我可以更新正则表达式以适应其他情况。

代码

See regex in use here

<强>正则表达式

(?:^|,\s*)\K(\.foo-bar)(?=\s*(?:,|{))

<强>替换

UNUSED $1

注意:使用多行m标记。

用法

regex101生成以下脚本(通过单击regex101中的代码生成器):Link here

$re = '/(?:^|,\s*)\K(\.foo-bar)(?=\s*(?:,|{))/m';
$str = '.foo-bar {}

.foo-bar, .bar-foo {}

.foo-bar .bar-foo {}

.boo-far, .foo-bar {}

.foo-bar,.bar-foo {}

.bar-foo.foo-bar {}';
$subst = 'UNUSED $1';

$result = preg_replace($re, $subst, $str);

echo "The result of the substitution is ".$result;

结果

输入

.foo-bar {}

.foo-bar, .bar-foo {}

.foo-bar .bar-foo {}

.boo-far, .foo-bar {}

.foo-bar,.bar-foo {}

.bar-foo.foo-bar {}

输出

UNUSED .foo-bar {}

UNUSED .foo-bar, .bar-foo {}

.foo-bar .bar-foo {}

.boo-far, UNUSED .foo-bar {}

UNUSED .foo-bar,.bar-foo {}

.bar-foo.foo-bar {}

说明

  • (?:^|,\s*)匹配以下任一项
    • ^在行首处断言位置
    • ,\s*字面上的逗号字符,,后跟任意数量的空白字符
  • \K重置报告的匹配的起点(任何以前消费的字符不再包含在最终匹配中)
  • (\.foo-bar)从字面上捕获到第1组:点字符.,然后依次为foo-bar
  • (?=\s*(?:,|{))确定以下内容的正向前瞻符合以下内容
    • \s*任意次数的空白字符
    • (?:,|{))匹配以下任一项
      • ,逗号字符,字面意思
      • {左大括号{字面意思

修改

以下正则表达式是前一个正则表达式的更新,并将\s*移到第一个组之外,以匹配插入符^之后的空格的可能性。

(?:^|,)\s*\K(\.foo-bar)(?=\s*(?:,|{))