Regex for hexadecimal colors

Asked

Viewed 243 times

1

I have a small doubt: I have a regex that captures in 3 groups (2 values per group) of certain color, but this when I have 6 values(excluding the #), I would like to know how to implement to catch 1 group when color is for example: #333 and 3 groups when you are for example #628F61?

Example 1

For example, user entered:

#fff

and the regex returns 1 group with:

fff

Example 2

inserted:

#F00000

returns 3 groups:

  1. F0
  2. 00
  3. 00

So far I’ve done it:

#?(\w{2})(\w{2})(\w{2})
  • 1

    A if which checks the length of string does not solve no?

3 answers

5


To answer the question, here is the version with regex:

#?(([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})|([0-9a-f])([0-9a-f])([0-9a-f]))

This Regex separates by 3 groups of two hexa characters, or 3 groups of one hexa character each.

To take advantage of the output without much complexity, you can concatenate the groups 2 and 5, 3 and 6, 4 and 7 respectively, because only one of each pair will be filled.

#?(([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})|([0-9a-f]{3}))

This is the "original" of the question, with 3 or 1 group.

Simple and direct version without regex:

For this kind of trouble, I think regex although it appears to be shorter, it is of an unnecessary complexity, both to be processed and to be debugged, so I decided to put this basic example using "traditional programming".

Works with or without # at the beginning, and with 3 or 6 digits.

color = "#bacc01"

if color[0]=="#":
   color = color[1:]

if len(color) == 3:
   r = color[0]
   g = color[1]
   b = color[2]

else:
   r = color[0:2]
   g = color[2:4]
   b = color[4:6]

print( "red  ", r )
print( "green", g )
print( "blue ", b )

Exit:

red   ba
green cc
blue  01

To adapt to #abc go out in one group, just change what is inside the if initial.

  • Thank you so much for your help! + 1

1

Here comes the expression:

^#((\w{2})(\w{2})(\w{2})|(\w{3}))$

I basically added a new condition for the 3-character case, and also a $, indicating that the string should end there.

As a bonus, here is an expression to detect a color string with 3 or 6 characters (but without taking the 3 groups):

^#(?:[0-9a-f]{3}){1,2}$

1

This expression should work in your case:

^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})|([0-9a-fA-F]{3})$

Will return one group for colors like #fff 333 #333. Or else you will return three groups for colors like #ffffff ff33FF #333333.

Note also that the expression has the character ^ at the beginning of the line and the $ at the end, it is available to remove them. In this expression only hexadecimal characters are accepted and the # is optional.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.