Skip to content

How to Validate Hex Color Format String in Python

Learn how to validate hex color codes (e.g., #FF5733 or #FFF) in Python using regex patterns or manual conversion to ensure correct format for web development, design tools, and data visualization.

In web development, graphic design tools, and data visualization, colors are frequently represented as Hexadecimal strings (e.g., #FF5733 or #FFF). Validating these strings is essential to prevent rendering errors or database corruption when processing user input.

This guide explores how to validate Hex color codes using Regular Expressions (Regex) and Python's built-in type conversion logic.

Understanding the Hex Color Format

A valid Hex color code follows specific rules:

  1. Prefix: It often starts with a hash symbol (#).
  2. Characters: It contains only hexadecimal digits: 0-9 and A-F (case-insensitive).
  3. Length: It must be either 6 digits (standard) or 3 digits (shorthand).
    • Standard: #RRGGBB (e.g., #FF0000 is Red).
    • Shorthand: #RGB (e.g., #F00 expands to #FF0000).

The most robust way to validate a specific pattern string is using the re module. A single regex pattern can enforce length, allowed characters, and the optional hash prefix simultaneously.

The Pattern: ^#?(?:[0-9a-fA-F]{3}){1,2}$

  • ^ : Start of string.
  • #? : Optional hash symbol.
  • (?: ... ) : Non-capturing group.
  • [0-9a-fA-F]{3} : Exactly 3 hex characters.
  • {1,2} : The previous group appears 1 time (3 chars) or 2 times (6 chars).
  • $ : End of string.
import re

def is_valid_hex(hex_code):
    pattern = r"^#?(?:[0-9a-fA-F]{3}){1,2}$"
    
    return bool(re.fullmatch(pattern, hex_code))

print(f"#FFF:     {is_valid_hex('#FFF')}")          # True (3 digits)
print(f"#FF5733:  {is_valid_hex('#FF5733')}")       # True (6 digits)
print(f"abc:      {is_valid_hex('abc')}")           # True (No hash is often valid logic)
print(f"#ZZZ:     {is_valid_hex('#ZZZ')}")          # False (Invalid chars)
print(f"#12345:   {is_valid_hex('#12345')}")        # False (Invalid length)

Output:

abc:      True

Method 2: Using int() Conversion (No Regex)

If you prefer to avoid Regular Expressions, you can validate the logic by attempting to convert the string into an integer with base 16. You must also manually check the string length.

def validate_hex_manual(hex_code):
    clean_code = hex_code.lstrip('#')
    
    if len(clean_code) not in (3, 6):
        return False
        
    try:
        int(clean_code, 16)
        return True
    except ValueError:
        return False

print(f"Valid (#AABBCC): {validate_hex_manual('#AABBCC')}")
print(f"Invalid Length (#AABB): {validate_hex_manual('#AABB')}")
print(f"Invalid Char (#00GG00): {validate_hex_manual('#00GG00')}")

Output:

Valid (#AABBCC): True
Invalid Length (#AABB): False
Invalid Char (#00GG00): False

Method 3: Validating and Converting to RGB

Often, validation is just the first step before converting the Hex code into an RGB tuple (Red, Green, Blue). This function validates the input and returns the converted values if successful.

def hex_to_rgb(hex_code):
    hex_code = hex_code.lstrip('#')
    
    if not all(c in "0123456789abcdefABCDEF" for c in hex_code):
        return None
        
    if len(hex_code) == 3:
        hex_code = "".join(c*2 for c in hex_code)
        
    if len(hex_code) != 6:
        return None # Invalid length
        
    try:
        return tuple(int(hex_code[i:i+2], 16) for i in (0, 2, 4))
    except ValueError:
        return None

print(f"Convert #FF0000: {hex_to_rgb('#FF0000')}")
print(f"Convert #0F0:    {hex_to_rgb('#0F0')}") # Shorthand

print(f"Convert #XYZ:    {hex_to_rgb('#XYZ')}")

Output:

Convert #FF0000: (255, 0, 0)
Convert #0F0:    (0, 255, 0)
Convert #XYZ:    None

Conclusion

To validate hex colors in Python:

  1. Use Regex (re.fullmatch) for the most concise and standard pattern matching.
  2. Use int(val, 16) inside a try-except block if you want to avoid importing the regex library.
  3. Check Lengths strictly (3 or 6 characters) after removing the # prefix.
Navigation