颜色名称合法性取决于下游系统标准,CSS规范定义了140+个命名色(如"red"、"rebeccapurple"),应使用小写哈希表O(1)查找并预处理空格与大小写。

颜色名称合法性取决于你用在哪种标准里
没有统一的“C++ 颜色名称标准”,std::string 本身不校验颜色。所谓“合法”,实际是指该字符串是否被下游系统(如 CSS 解析器、GUI 框架、Web 渲染引擎)认可为预定义颜色名。最常用、最权威的参考是 CSS 规范定义的 named-color,共 140+ 个(CSS Color Module Level 4),比如 "red"、"rebeccapurple"、"transparent"。
用静态哈希表快速查 CSS 标准颜色名
别用 std::vector 或线性查找——颜色名数量固定且不多,O(1) 查找更合理。C++17 起可用 std::unordered_set 初始化列表构造;C++20 起推荐 std::unordered_set + constexpr 哈希(但注意编译器支持度)。实际项目中更稳妥的是:
- 把所有 CSS named colors 写成 C 字符串数组,用
std::unordered_set<:string_view></:string_view>初始化(避免重复构造std::string) - 查找前先
std::tolower转小写(CSS 颜色名不区分大小写,"Red"和"RED"都合法) - 注意空格和首尾空白:
" red "不合法,需提前trim
示例片段:
static const std::unordered_set<std::string_view> kCssNamedColors = {
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure",
"beige", "bisque", "black", "blanchedalmond", "blue",
// ... 全部 140+ 个,省略
"white", "whitesmoke", "yellow", "yellowgreen"
};
bool IsValidCssColorName(const std::string& s) {
if (s.empty()) return false;
std::string lower = s;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
// 这里应加上 trim 逻辑(略),否则 " red " 会查不到
return kCssNamedColors.find(lower) != kCssNamedColors.end();
}
别忘了十六进制和 rgb() 等格式不是“颜色名称”
用户问的是“颜色名称”,不是“颜色值”。所以 "#ff0000"、"rgb(255,0,0)"、"hsl(0,100%,50%)" 都不属于本问题范畴——它们是颜色表示法,不是名称。若你实际需要的是“任意合法 CSS 颜色值”,那得另写解析器(或用第三方库如 css-color-parser),不能只查名字表。
立即学习“C++免费学习笔记(深入)”;
- 检查前先明确输入预期:是纯名称?还是可能混入其他格式?
- 如果允许缩写如
"#f00",它也不是名称,是十六进制简写 -
"currentcolor"是 CSS 关键字,属于 named-color,要包含在表中
Windows GDI / Qt / Skia 等平台有自己的颜色名表
如果你不是对接 Web/CSS,而是调 SetTextColor、QColor::fromString 或 Skia 的 SkColors::kRed,那“合法”的定义就变了。例如:
- Windows GDI 几乎不认颜色名,只认 RGB 值;
GetStockObject(BLACK_BRUSH)是另一套机制 - Qt 的
QColor构造函数支持 CSS 名称(内部用了类似上面的表),但也支持"red"、"darkRed"这类 Qt 扩展名——这些不在 CSS 标准里 - Skia 完全不提供名称解析,只接受
SkColor整数
所以务必确认你的目标 API 文档。Qt 用户直接用 QColor color(s); return color.isValid(); 最省事;而跨平台底层库必须自己维护对应表。
真正容易被忽略的是大小写处理和空白字符——很多实现直接拿原始字符串去查,结果 "Red " 或 "RED" 就判失败;还有人把 "transparent" 漏掉,但它确实是 CSS named-color 且广泛支持。


















