1

I have svg file which is stored in string format in javascript. I want to extract all the colors mentioned in file and stored it in array.

color information would be denoted as fill:#010101; in file. I want to

  1. search :# characted in file
  2. Extract assosoate hex color
  3. Store it in array
  4. Again search for next color

SVG File could vary from size 1kb to 450Kb. I can use .indexOf to find first occurence of :# but i am stuck in which method to use to get all colors in efficient way.

Here is a fiddle of what i have done : http://jsfiddle.net/mumg81qq/1/ even fiddle gets hanged due to my svg string :(

Edit : How to modify Javascript regex. Need to extract value from a SVG string this answer to get hex/rgb colors from svg string ?

Community
  • 1
  • 1
Shaggy
  • 5,422
  • 28
  • 98
  • 163
  • Will the SVG file change frequently, or is this more or less a static list? – robbmj Apr 23 '15 at 14:13
  • @robbmj It will remain static – Shaggy Apr 23 '15 at 14:14
  • Could you not process the SVG file once and store the results in a JSON string. When the client needs the colours it could request the JSON from the server. – robbmj Apr 23 '15 at 14:15
  • @robbmj : Do u mean color extraction process is handled by server side code ? and extract colors are requested by ajax call ? – Shaggy Apr 23 '15 at 14:17
  • Yep that is what I mean. And if the list never changes you only need to process the file once. And even if it does change at least the AJAX call does not block the UI. – robbmj Apr 23 '15 at 14:18

3 Answers3

3

I don't know how efficient a regular expression would be at handling this, but something like this could work (however slow it may be) http://jsfiddle.net/vdugk40m/1/:

var info="fill:#010011;fill:#010012;fill:#010013;fill:#010014;";
var m, regex = /fill\:\#(\[A-F0-9]+)[;]/gi;
var colors = [];

do {
    m = regex.exec(info);
    if (m)
        colors.push(m[1]);
} while (m);

alert(colors);

If you need the # in the string, move the open parenthesis before the \#.

If you want to then reduce the array to only unique values (lifted from https://stackoverflow.com/a/14438954/579148):

colors = colors.filter( onlyUnique );

function onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
}
Community
  • 1
  • 1
jwatts1980
  • 7,254
  • 2
  • 28
  • 44
2

If you just want to capture hex values (i.e 6 characters following #) regexp groups comes in handy

var r = new RegExp('fill:#([a-zA-Z0-9]{6})','g')
var res= [];
while(result = r.exec(file)) { 
   res.push(result[1]); 
}

In the code piece above, I matched the 6 characters after #, and stored the captured group in an array called res

Here is a modified version of your fiddle to demonstrate

http://jsfiddle.net/mumg81qq/3/

JuniorDev
  • 1,170
  • 2
  • 9
  • 19
2

I like to keep it short, so here's my attempt:

var colors = [];
file.replace(/fill:(#[abcdef0-9]{6})/ig, function(v, c) { colors.push(c); return v; });

Will populate the array colors as you can see here: http://jsfiddle.net/ks92aau8/

Keep in mind that if you plan to support RGBA (alpha transparency) values, you'll need to use {8} instead of {6} in the regex.

Constantin Groß
  • 10,719
  • 4
  • 24
  • 50