$regex(hex_code, $$1, /(\d{3})/)
this will never return anything other than 0 or 1 since you haven't used the //g modifier i.e. /(\d{3})/
g (which makes it continue past a first successful match) but that still wouldn't work as you expect. the way a regular expression is matched against the string, it consumes the string as it moves through it. so let's suppose the regex matching
point is at the start of "829879". after \d{3} is matched, the matching point is after "829" and during the next cycle.. it starts where it left off and attempts to match \d{3} here in the middle: 829
|879
if you want it to match these overlapping occurences of numbers, you'll need to progress through the series of matches one character at a time, but at the same time check that there exists 3 numbers in a row without the matching point progressing past them. this can be done with a zero width assertion:
$regex(hex_code, $$1, /(?=(\d{3}))/g)
(?=) takes a look ahead to see if \d{3} is matched, without actually consuming those characters. since (?=) is zerowidth, that expression actually matches a position in the string, before any group of 3 numbers
the problem with the other two is quite simply that [:xdigit:] itself belongs inside a character class,
[[:xdigit:]] allowing you to do such things as [A-Z[:xdigit:]a-z] etc.