gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 08:06:31 24 4
gpt4 key购买 nike

简介:

我对 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com