gpt4 book ai didi

php - str_replace 基于 CSS 注释的 CSS 属性

转载 作者:太空宇宙 更新时间:2023-11-03 22:03:37 26 4
gpt4 key购买 nike

我正在构建一个“主题生成器”,它将动态地即时编辑 CSS 文件。我认为使用 PHP 是最简单的选择(愿意考虑其他方法)。

我的 CSS 文件在每个属性后包含注释,如下所示:

html,body {
background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/
color: #fff; /*{textColor}*/
}

是否可以使用替换功能来搜索该评论并仅替换它之前的代码?用户可能希望在完成构建主题后返回并再次更改某些内容,因此评论必须始终保留。

谢谢

最佳答案

只要您遵循在行尾有 varname 并且每行仅包含一个 CSS property : value 的模式,您就可以它使用基于正则表达式的搜索和替换。

如果你想这样做,请注意新值不包含任何 PCRE 意义上的换行符:\r\n|\n|\x0b|\f|\r|\x85 (非 UTF-8 模式)。如果不这样做,这将破坏您的解析器!

为此,您可以为模式创建一个掩码,以便稍后轻松插入变量名,我通常使用 sprintf为此:

$patternMask = 
'~
^ # start of line

(\s*[a-z]+:\s*)
# Group 1:
# whitespace (indentation)
# + CSS property and ":"
# + optional whitespace

(.*?) # Group 2: CSS value (to replace)

(\s*/\*\{%s\}\*/\s*)
# Group 3:
# whitespace (after value and before variable)
# + variable comment, %%s is placeholder for it\'s name

$ # end of line

# Pattern Modifiers:
# m: ^ & $ match begin/end of each line
# x: ignore spaces in pattern and allow comments (#)
~mx'
;

这是带有注释的正则表达式模式,可以通过 x 修饰符实现。只是为了让您更容易理解。

重要的一点是用于多行模式的 m 修饰符。该模式应该在每一行上工作,所以它被包含在 ^ (开始)和 $ (结束)中,这将匹配多行中一行的开始和结束模式。

当您进行替换操作时,组 2 将被替换,组 1 和组 3 将被保留。完成后,结果仍将包含变量名称。

然后通过使用 sprintfpreg_quote 将正确引用的变量名称添加到其中,使用此掩码构建实际的正则表达式模式。 :

$varName = 'bgColor';
$value = '#f00 url(../images/bg-reg.jpg) repeat-x;';

# create regex pattern based on varname
$pattern = sprintf($patternMask, preg_quote($varName, $patternMask[0]));

$patternMask[0]~ 所以如果你的变量名包含 ~ 它会自动正确转义。

搜索模式现已完成。剩下的就是替补。作为变量名,替换字符串也需要转义以不破坏它的正则表达式(语法错误)。此外,如前所述,整个过程需要注意将新字符串保留为单行,否则下次执行替换操作会破坏它。因此,为防止这种情况,任何换行符都将替换为 $value 中的单个空格,以防止出现这种情况:

# replace characters that will break the pattern with space
$valueFiltered = str_replace(explode('|', "\r\n|\n|\x0b|\f|\r|\x85"), ' ', $value);

然后特殊字符 \$ 将被引用,这样它们就不会干扰替换模式并且替换字符串被构建。这是通过 addcslashes 完成的功能:

# escape $ characters as they have a special meaning in the replace string 
$valueEscaped = addcslashes($valueFiltered, '\$');
$replace = sprintf('${1}%s$3', $valueEscaped);

唯一剩下的就是运行替换操作,所以预先给它一些 CSS:

$css = <<<CSS
html,body {
background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/
color: #fff; /*{textColor}*/
}
CSS;

并运行替换为 preg_replace :

$newCss = preg_replace($pattern, $replace, $css);

这就是全部了。来自原始 CSS:

html,body {
background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/
color: #fff; /*{textColor}*/
}

到结果 CSS:

html,body {
background: #f00 url(../images/bg-reg.jpg) repeat-x; /*{bgColor}*/
color: #fff; /*{textColor}*/
}

如果您使用 preg_replace&$count 参数,您可以检查变量是否是字符串的一部分:

$newCss = preg_replace($pattern, $replace, $css, -1, $count);

$count 在给定的示例中为 1。

如果您想一次替换多个值,您可以使用数组作为 $pattern$replace 以备不时之需。 $count 仍然是一个整数,因此它的用途可能有限。

整个代码一目了然:

$css = <<<CSS
html,body {
background: #fff url(../images/bg.jpg) repeat-x; /*{bgColor}*/
color: #fff; /*{textColor}*/
}
CSS;


$patternMask =
'~
^ # start of line

(\s*[a-z]+:\s*)
# Group 1:
# whitespace (indentation)
# + CSS property and ":"
# + optional whitespace

(.*?) # Group 2: CSS value (to replace)

(\s*/\*\{%s\}\*/\s*)
# Group 3:
# whitespace (after value and before variable)
# + variable comment, %%s is placeholder for it\'s name

$ # end of line

# Pattern Modifiers:
# m: ^ & $ match begin/end of each line
# x: ignore spaces in pattern and allow comments (#)
~mx'
;

$varName = 'bgColor';
$value = '#f00 url(../images/bg-reg.jpg) repeat-x;';

# create regex pattern based on varname
$pattern = sprintf($patternMask, preg_quote($varName, $patternMask[0]));

# replace characters that will break the pattern with space
$valueFiltered = str_replace(explode('|', "\r\n|\n|\x0b|\f|\r|\x85"), ' ', $value);

# escape $ characters as they have a special meaning in the replace string
$valueEscaped = addcslashes($valueFiltered, '\$');

$replace = sprintf('${1}%s$3', $valueEscaped);

$newCss = preg_replace($pattern, $replace, $css);

echo $newCss;

关于php - str_replace 基于 CSS 注释的 CSS 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8552154/

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