php - 删除依赖于 RegEx 类的 CSS 规则

标签 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>');
}
?>

最佳答案

回答

简介

根据您提供的示例,以下正则表达式将起作用,但它不适用于所有 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*(?:,|{))

关于php - 删除依赖于 RegEx 类的 CSS 规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46584313/

相关文章:

php - 在 MySQL 和 url mod_rewrite 中组织博客类别的最优化方式?

php - 无法从 Soap 响应中提取数据

php - 搜索多行mysql

html - Bootstrap 3.0 模态分隔宽度布局

python - 匹配具有特定字符串的行以提取值 Python Regex

javascript - jQuery,提交不是在表单上取消

css - 行间距和混合字体大小

html - 固定背景图像的对齐问题

javascript - 用引号分割文本而不是javascript中的空格

javascript - 检查后行断言的兼容性