如何识别给定的字符串是十六进制颜色格式

我正在寻找一个正则表达式来验证 ASP.NET C # 和十六进制颜色
我也期待在服务器端验证代码。

例如: #CCCCCC

65305 次浏览

Note: This is strictly for validation, i.e. accepting a valid hex color. For actual parsing you won't get the individual parts out of this.

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

For ARGB:

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

Dissection:

^              anchor for start of string
#              the literal #
(              start of group
?:            indicate a non-capturing group that doesn't generate backreferences
[0-9a-fA-F]   hexadecimal digit
{3}           three times
)              end of group
{1,2}          repeat either once or twice
$              anchor for end of string

This will match an arbitrary hexadecimal color value that can be used in CSS, such as #91bf4a or #f13.

Minor disagreement with the other solution. I'd say

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

The reason is that this (correctly) captures the individual RGB components. The other expression broke #112233 in three parts, '#' 112 233. The syntax is actually '#' (RR GG BB) | (R G B)

The slight disadvantage is more backtracking is required. When parsing #CCC you don't know that the second C is the green component until you hit the end of the string; when parsing #CCCCCC you don't know that the second C is still part of the red component until you see the 4th C.

It also works great for RGBA but the other solution doesn't

const thisRegex = /#(([0-9a-fA-F]{2}){3,4}|([0-9a-fA-F]){3,4})/g
document.write("#fff;ae#rvaerv c #fffaff---#afd #ffff".match(thisRegex))
// #fff,#fffaff,#afd,#ffff

the other solution doesn't recognize #fffaff well

const theOtherSolutionRegex = /#(?:[0-9a-fA-F]{3,4}){1,2}/g
document.write("#fff;ae#rvaerv c #fffaff---#afd #ffff".match(theOtherSolutionRegex))
// #fff,#fffa,#afd,#ffff

This if you want to accept named colors and rgb(a,b,c) too. The final "i" is for case insensitive.

HTML colors (#123, rgb not accepted)

/^(#[a-f0-9]{6}|black|green|silver|gray|olive|white|yellow|maroon|navy|red|blue|purple|teal|fuchsia|aqua)$/i

CSS colors (#123, rgb accepted)

/^(#[a-f0-9]{6}|#[a-f0-9]{3}|rgb *\( *[0-9]{1,3}%? *, *[0-9]{1,3}%? *, *[0-9]{1,3}%? *\)|rgba *\( *[0-9]{1,3}%? *, *[0-9]{1,3}%? *, *[0-9]{1,3}%? *, *[0-9]{1,3}%? *\)|black|green|silver|gray|olive|white|yellow|maroon|navy|red|blue|purple|teal|fuchsia|aqua)$/i

Based on MSalters' answer, but preventing an incorrect match, the following works

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

Or for an optional hash # symbol:

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

And without back references being generated:

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

all answers mentioned RGB format, here is regex for ARGB format:

^#[0-9a-fA-F]{8}$|#[0-9a-fA-F]{6}$|#[0-9a-fA-F]{4}$|#[0-9a-fA-F]{3}$

This should match any #rgb, #rgba, #rrggbb, and #rrggbbaa syntax:

/^#(?:(?:[\da-f]{3}){1,2}|(?:[\da-f]{4}){1,2})$/i

break down:

^            // start of line
#            // literal pound sign, followed by
(?:          // either:
(?:          // a non-capturing group of:
[\da-f]{3}   // exactly 3 of: a single digit or a letter 'a'–'f'
){1,2}       // repeated exactly 1 or 2 times
|            // or:
(?:          // a non-capturing group of:
[\da-f]{4}   // exactly 4 of: a single digit or a letter 'a'–'f'
){1,2}       // repeated exactly 1 or 2 times
)
$            // end of line
i            // ignore case (let 'A'–'F' match 'a'–'f')

Notice that the above is not equivalent to this syntax, which is incorrect:

/^#(?:[\da-f]{3,4}){1,2}$/i

This would allow a group of 3 followed by a group of 4, such as #1234567, which is not a valid hex color.

Ruby

In Ruby, you have access to the \h (hexadecimal) character class. You also have to take more care of line endings, hence the \A...\z instead of the more common ^...$

/\A#(\h{3}){1,2}\z/

This will match 3 or 6 hexadecimal characters following a #. So no RGBA. It's also case-insensitive, despite not having the i flag.