views:

89

answers:

4

Greetings JavaScript and regular expression gurus,

I want to return all matches in an input string that are 6-digit hexadecimal numbers with any amount of white space in between. For example, "333333 e1e1e1 f4f435" should return an array:

array[0] = 333333  
array[1] = e1e1e1  
array[2] = f4f435

Here is what I have, but it isn't quite right-- I'm not clear how to get the optional white space in there, and I'm only getting one match.

colorValuesArray = colorValues.match(/[0-9A-Fa-f]{6}/);

Thanks for your help,

-NorthK

+3  A: 

Use the g flag to match globally:

/[0-9A-Fa-f]{6}/g

Another good enhancement would be adding word boundaries:

/\b[0-9A-Fa-f]{6}\b/g

If you like you could also set the i flag for case insensitive matching:

/\b[0-9A-F]{6}\b/gi
Gumbo
Though, this does allow _any_ characters between the numbers, not just whitespace.
bdukes
Thanks Gumbo, that did the trick!
northk
Hmmm, I think any allowing any characters between matches is OK in this case; thanks bdukes.
northk
@bdukes: Word boundaries require a change from word characters (`\w`) to non-word characters (`\W`) or vice versa or the start or the end of the string. So the character before and after our `[0-9A-F]{6}` must be non-word characters or the start or end of the string.
Gumbo
The characters before and after any 6-digit number must be a non-word character, but you can have other nonsense inbetween, like `"333333 X e1e1e1 f4f435"`
bdukes
@bdukes: Sure, but the `X` wouldn’t be matched.
Gumbo
@Gumbo: exactly, just saying that it allows extra characters between the numbers, so this wouldn't be a solution if only whitespace were allowed between the numbers.
bdukes
A: 

try:

colorValues.match(/[0-9A-Fa-f]{6}/g); 

Note the g flag to Globally match.

Kyle Butt
A: 
result = subject.match(/\b[0-9A-Fa-f]{6}\b/g);

gives you an array of all 6-digit hexadecimal numbers in the given string subject.

The \b word boundaries are necessary to avoid matching parts of longer hexadecimal numbers.

Tim Pietzcker
Ahh, good point Tim, thanks.
northk
+1  A: 

It depends on the situation, but I usually want to make sure my code can't silently accept (and ignore, or misinterpret) incorrect input. So I would normally do something like this.

var arr = s.split();
for (var i = 0; i < arr.length; i++) {
    if (!arr[i].match(/^[0-9A-Fa-f]{6}$/)
        throw new Error("unexpected junk in string: " + arr[i]);
    arr[i] = parseInt(arr[i], 16);
}
Jason Orendorff
Thanks Jason.in this case I think it's OK 'cause the user will immediately see the results graphically of what they typed in if they typed in garbage :)
northk