2014-04-08 23 views
0

我有填充SVG文件上的路径如下所示:preg_replace函数的正则表达式匹配6个相同的字符

<path fill="#FFFFFF" ... /> 
<path fill="#CCCCCC" ... /> 
<path fill="#DDDDDD" ... /> 

我可以通过替换那些6个以字符的3个相同字符的任何填充稍微降低文件大小,产生:

<path fill="#FFF" ... /> 
<path fill="#CCC" ... /> 
<path fill="#DDD" ... /> 

我不知道怎么在我的PHP preg_replace的正则表达式将查找此。我想它会像这样开始:

$fileContent = preg_replace('/fill="#/','',$fileContent); 

请注意,6个相同的字符可以是字母数字,可以是任何颜色,不只是我的例子。

回答

3

试试这个:

$text = <<<EOT 
<path fill="#FFFFFF" ... /> 
<path fill="#CCCCCC" ... /> 
<path fill="#DDDDDD" ... /> 
EOT; 

$text = preg_replace('/fill="#(.)\1{5}/', 'fill="#$1$1$1', $text); 
print "$text\n"; 

这里(.)捕获的第一个字符,并使用反向引用\1{5}它会检查下一个五个字符相同与否。如果是,则用三个$1替换,其中保留正则表达式中使用的值(.)

+1

这是一个很好的答案,我可能会用正则表达式'/ fill =“#([\ da-f])\ 1 {5}/i'来匹配0-9和AF ,不区分大小写 –

+0

真棒感谢哥们! – Coop

1

尝试使用back references,例如:

$fileContent = preg_replace('/(fill="#)(.)\2{5}/', '\1\2\2\2', $fileContent); 

这会匹配fill="#XXXXXX任何字符串,并与像fill="#XXX字符串替换它。

但是,十六进制颜色代码如#FFCC99can also be shortened#FC9。如果你想处理这种情况,以及,你可以尝试这样的事:

$fileContent = preg_replace('/(fill="#)(.)\2(.)\3(.)\4/', '\1\2\3\4', $fileContent); 

这将匹配任何字符串像fill="#XXYYZZ,并与像fill="#XYZ字符串替换它。

+0

但我只想匹配像6点相同的字符'补=“#FFFFFF”'不是东西,比如'补=“#F8F8F8”'或'补=“#FFCCAA”' – Coop

+0

@Coop那么,如果这是一个要求,看到我的更新答案替代。顺便说一句,这些模式都不会匹配'fill =“#F8F8F8”'。 –

+0

这似乎是最合理的 –

-1

快速和肮脏的解决办法是:

$regex = "/#(0{6}|1{6}|...|E{6}|F{6}/"; 

不是最完美的解决方案,但它会完成这项工作。

2

您可以使用:

$s = '<path fill="#FFFFFF" ... />'; 
echo preg_replace('/(fill="#)([0-9A-F])\g{-1}{5}/i', '$1\2\2\2', $s); 
//=> <path fill="#FFF" ... /> 

哪里\g{-1}是反向引用最近的组。

+1

我以前从来没有使用过'\ g {-1}',它对我来说是新的,谢谢。 –

+0

我相信这是PCRE功能,虽然还没有在Javascript上试过。 – anubhava

+1

有趣,阅读从'\ g'已经,但不是''g {-1}'感谢输入:)非常好! –