CaribouCode
CaribouCode

Reputation: 14438

preg_replace regex to match 6 identical characters

I have SVG files with fills on paths like so:

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

I can reduce file sizes slightly by replacing any fills that are 6 identical characters with 3 of the characters, producing:

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

I'm not sure how the regex in my php preg_replace would look for this. I imagine it would start like this:

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

Note the 6 identical characters can be alphanumeric and could be any color, not just my examples.

Upvotes: 0

Views: 103

Answers (4)

p.s.w.g
p.s.w.g

Reputation: 149078

Try using back references, for example:

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

This will match any string like fill="#XXXXXX and replace it with a string like fill="#XXX.

However, hexadecimal color codes like #FFCC99 can also be shortened to #FC9. If you'd like to handle that case as well, you can try something like this:

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

This will match any string like fill="#XXYYZZ and replace it with a string like fill="#XYZ.

Upvotes: 1

anubhava
anubhava

Reputation: 786291

You can use:

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

Where \g{-1} is back reference to most recent group.

Upvotes: 2

Sabuj Hassan
Sabuj Hassan

Reputation: 39443

Try this:

$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";

Here (.) captures the first character and using backreference \1 with {5} it checks that the next five characters are same or not. If yes, then replace with three $1 which holds the value from (.) used in regex.

Upvotes: 3

Kryten
Kryten

Reputation: 15780

A quick-and-dirty solution would be:

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

Not the most elegant solution, but it will get the job done.

Upvotes: -1

Related Questions