只要你按照你有varname
在该行的结束,每一行包含一个CSS property : value
而已,你可以在模式用正则表达式进行搜索和替换。
如果您想这样做,请注意新值在PCRE意义上不包含任何newline-ish:\r\n|\n|\x0b|\f|\r|\x85
(非UTF-8模式)。如果你不这样做,这会破坏你的解析器!
要做到这一点,你可以创建为图案的面具,让你可以再插入VARNAME以后很容易,我通常使用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
-修改器。该模式应该适用于每一行,因此它被包含在^
(Begin)和$
(End)中,它将与多行模式下行的开始和结束相匹配。
当您进行替换操作时,组2将被替换,组1和3将被保留。完成后,结果仍将包含变量名称。
实际的正则表达式,然后通过使用sprintf
和preg_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);
剩下的唯一的事情就是运行更换操作,所以给它ssome 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;
向一个具体的问题,你跑?只需在该行末尾重新添加注释,它应该没问题。 – hakre 2011-12-18 13:54:14
啊我明白了。在这种情况下,我将如何搜索评论,然后替换整个行? – tctc91 2011-12-18 14:02:02
预期产量是多少?第一行不明确,因为'bgColor'属性转换为'background-color'。 – 2011-12-18 14:08:59