如何检查字符串是不是是有效的十六进制颜色表示?

Posted

技术标签:

【中文标题】如何检查字符串是不是是有效的十六进制颜色表示?【英文标题】:How to check if a string is a valid hex color representation?如何检查字符串是否是有效的十六进制颜色表示? 【发布时间】:2011-12-23 01:37:45 【问题描述】:

例如:

AA33FF = 有效的十六进制颜色

Z34FF9 = 无效的十六进制颜色(其中包含 Z)

AA33FF11 = 无效的十六进制颜色(有多余的字符)

【问题讨论】:

根据上下文,如果最后一个颜色包含AARRGGBB 格式的alpha,则它可能是有效颜色。 这能回答你的问题吗? How to identify a given string is hex color format 【参考方案1】:
/^#[0-9A-F]6$/i.test('#AABBCC')

详细说明:

^ -> 匹配开头# -> 哈希[0-9A-F] -> 0 到 9 之间的任意整数和 A 到 F 之间的任意字母6 -> 前一组恰好出现 6 次$ ->匹配结束i ->忽略大小写

如果您需要支持 3 个字符的 HEX 代码,请使用以下代码:

/^#([0-9A-F]3)1,2$/i.test('#ABC')

这里唯一的区别是

 [0-9A-F]6

替换为

([0-9A-F]3)1,2

这意味着它不会精确匹配 6 个字符,而是精确匹配 3 个字符,但只匹配 1 或 2 次。允许ABCAABBCC,但不允许ABCD

组合解决方案:

var reg=/^#([0-9a-f]3)1,2$/i;
console.log(reg.test('#ABC')); //true
console.log(reg.test('#AABBCC')); //true

【讨论】:

根据定义这是正确的,但长度为 3 的代码也适用于浏览器解释。 color: #f00; 也将被解释为红色 (#ff0000)。 或其他形式:/^#[0-9a-f]3(?:[0-9a-f]3)?$/i.test("#f00") 我还会添加/^#([0-9a-f]3)1,2$/i @AndresSepar /^#[0-9A-F]3,6$/i.test('#aabb') 也通过了,但 #aabb 不是有效的十六进制颜色。 var isOk = /^#([A-Fa-f0-9]6|[A-Fa-f0-9]3)$/i.test('#aabbcc '); @RomanBoiko 这是对的!谢谢!【参考方案2】:

// regular function
function isHexColor (hex) 
  return typeof hex === 'string'
      && hex.length === 6
      && !isNaN(Number('0x' + hex))


// or as arrow function (ES6+)
isHexColor = hex => typeof hex === 'string' && hex.length === 6 && !isNaN(Number('0x' + hex))

console.log(isHexColor('AABBCC'))   // true
console.log(isHexColor('AABBCC11')) // false
console.log(isHexColor('XXBBCC'))   // false
console.log(isHexColor('AAXXCC'))   // false

这个答案过去常常抛出误报,因为它使用的是parseInt(hex, 16),而不是Number('0x' + hex)parseInt() 将从字符串的开头开始解析,直到它到达一个不包含在基数中的字符(16)。这意味着它可以解析像“AAXXCC”这样的字符串,因为它以“AA”开头。

另一方面,

Number() 只会在整个字符串与基数匹配时进行解析。现在,Number() 不带 radix 参数,但幸运的是,您可以在数字文字前加上其他半径的数字。

这里有一个表格供澄清:

╭─────────────┬────────────┬────────┬───────────────────╮
│ Radix       │ Characters │ Prefix │ Will output 27    │
╞═════════════╪════════════╪════════╪═══════════════════╡
│ Binary      │ 0-1        │ 0b     │ Number('0b11011') │
│ Octal       │ 0-7        │ 0o     │ Number('0o33')    │
│ Decimal     │ 0-9        │ -      │ -                 │
│ Hexadecimal │ 0-9A-F     │ 0x     │ Number('0x1b')    │
╰─────────────┴────────────┴────────┴───────────────────╯

【讨论】:

+1 bcs 比正则表达式更好阅读和更快理解 @Chris 'because' 也比 'bcs' 更好阅读和更快理解 ;-) @Chris:我已经习惯了 'bcs' 对我来说并没有什么不同。无论如何,我的评论是一种恭维,所以要高兴。 这是错误的:parseInt('abcZab', 16) 将输出数字并通过测试 @fflorent 因为parseInt 会占用"abcZab",发现"Z" 无效(对于基数16),忽略它和它之后的任何东西。然后它将开头的"abc" 转换为2748(这也是parseInt("abcZab", 16) 的结果,证明这是发生的逻辑)。顾名思义,parseInt 解析一个字符串。就像如果您解析一个带有单位且基数为 10 的数字,例如parseInt("10px", 10),您将得到10。你可以在这里看到它的描述:es5.github.io/#x15.1.2.2(第 11 步)【参考方案3】:

这可能是一个复杂的问题。经过几次尝试,我想出了一个相当干净的解决方案。让浏览器为您完成工作。

第 1 步:创建一个边框样式设置为无的 div。 div 可以放置在屏幕外,也可以是页面上不使用边框的任何 div。

第 2 步:将边框颜色设置为空字符串。代码可能如下所示:

e=document.getElementbyId('mydiv');
e.style.borderColor="";

第 3 步:将边框颜色设置为您不确定的颜色。

e.style.borderColor=testcol;

第 4 步:检查颜色是否真的发生了变化。如果 testcol 无效,则不会发生变化。

col2=e.style.borderColor;
if(col2.length==0) alert("Bad Color!");

第 5 步:自行清理,将颜色设置回空字符串。

e.style.borderColor="";

分区:

<div id="mydiv" style="border-style:none; position:absolute; left:-9999px; top:-9999px;"></div>

现在是 javascript 函数:

function GoodColor(color)

   var color2="";
   var result=true;
   var e=document.getElementById('mydiv');
   e.style.borderColor="";
   e.style.borderColor=color;
   color2=e.style.borderColor;
   if (color2.length==0)result=false;
   e.style.borderColor="";
   return result;

在这种情况下,函数返回问题的真/假答案,另一个选项是让它返回一个有效的颜色值。您的原始颜色值,来自borderColor 的值或代替无效颜色的空字符串。

【讨论】:

IMO,这至少不是一个干净的解决方案【参考方案4】:
function validColor(color)
  var $div = $("<div>");
  $div.css("border", "1px solid "+color);
  return ($div.css("border-color")!="")

https://gist.github.com/dustinpoissant/22ce25c9e536bb2c5a2a363601ba261c

注意:这需要 jQuery

这适用于 ALL 颜色类型,而不仅仅是十六进制值。它还将不必要的元素添加到 DOM 树。

【讨论】:

很好,很简单,效果很好。我个人添加了 if(hexString.indexOf('#') == -1) return false; 来检查哈希值作为基本检查颜色是否为十六进制值【参考方案5】:

如果您需要一个函数来告诉您颜色是否有效,您不妨让它为您提供一些有用的东西——该颜色的计算值——并在它不是有效颜色时返回 null。这是我对兼容(Chrome54 和 MSIE11)函数的尝试,以获取任何格式的“颜色”的 RGBA 值——无论是“绿色”、“#FFF”、“#89abcd”还是“rgb” (0,0,128)' 或 'rgba( 0, 128, 255, 0.5)'。

/* getRGBA:
  Get the RGBA values of a color.
  If input is not a color, returns NULL, else returns an array of 4 values:
   red (0-255), green (0-255), blue (0-255), alpha (0-1)
*/
function getRGBA(value) 
  // get/create a 0 pixel element at the end of the document, to use to test properties against the client browser
  var e = document.getElementById('test_style_element');
  if (e == null) 
    e = document.createElement('span');
    e.id = 'test_style_element';
    e.style.width = 0;
    e.style.height = 0;
    e.style.borderWidth = 0;
    document.body.appendChild(e);
  

  // use the browser to get the computed value of the input
  e.style.borderColor = '';
  e.style.borderColor = value;
  if (e.style.borderColor == '') return null;
  var computedStyle = window.getComputedStyle(e);
  var c
  if (typeof computedStyle.borderBottomColor != 'undefined') 
    // as always, MSIE has to make life difficult
    c = window.getComputedStyle(e).borderBottomColor;
   else 
    c = window.getComputedStyle(e).borderColor;
  
  var numbersAndCommas = c.replace(new RegExp('[^0-9.,]+','g'),'');
  var values = numbersAndCommas.split(',');
  for (var i = 0; i < values.length; i++)
    values[i] = Number(values[i]);
  if (values.length == 3) values.push(1);
  return values;

【讨论】:

【参考方案6】:

如果您尝试在 html 中使用它,请尝试直接使用此模式:

 pattern="^#+([a-fA-F0-9]6|[a-fA-F0-9]3)$"

喜欢

<input id="hex" type="text" pattern="^#+([a-fA-F0-9]6|[a-fA-F0-9]3)$" />

它将提供验证以匹配请求的格式。

【讨论】:

【参考方案7】:

添加长度检查以确保不会误报

function isValidHex(testNum)
  let validHex = false;
  let numLength = testNum.length;
  let parsedNum = parseInt(testNum, 16);
  if(!isNan(parsedNum) && parsedNum.length===numLength)
     validHex = true;
  
  return validHex;

【讨论】:

【参考方案8】:

我决定尝试不同的视角。我的规则是:1)任意长的十六进制字符序列,2)在序列前面使用“0x”或“#”,或者3)只是一个十六进制数字或字符串。我回想起 binhex 是大型程序之一的时候。 Binhex 将创建非常大的文件,这些文件可以传输到任何地方,然后重新转换为您转换的任何文件。这些文件将有 80 个字符,后跟一个回车符。所以在这个函数中,我寻找回报并首先把它们拿出来。修改了函数,使其同时查找“\n”和“\r”。代码如下:

////////////////////////////////////////////////////////////////////////////////
//  isHex(). Is this a hex string/value?
//  Arguments   :   0   =   Item to test
//                  1   =   V(alue) or S(tring). Default is STRING.
////////////////////////////////////////////////////////////////////////////////
function isHex()

    var p = 0;
    var re1 = /(\n|\r)+/g;
    var re2 = /[\Wg-zG-Z]/;
    var re3 = /v/i;
//
//  Make sure the string is really a string.
//
    var s = arguments[0];
    if( typeof s != "string" ) s = s.toString(); 
//
//  Check if this is a hex VALUE
//  and NOT a hex STRING.
//
    var opt = arguments[1];
    if( re3.test(opt) && (s.length % 2 > 0) ) return "false"; 
//
//  Remove any returns. BinHex files can be megabytes in length with 80
//  column information. So we have to remove all returns first.
//
    s.replace( re1, "" );
//
//  IF they send us something with the universal "0x" or the HTML "#" on the
//  front of it - we have to FIRST move where we look at the string.
//
    if( s.substr(0,1) == "#" ) p = 1; 
        else if( s.substr(0,2).toLowerCase() == "0x" ) p = 2; 

   if( re2.test(s.substr(p,s.length)) ) return "false"; 

   return "true";


alert("HELLO There!");
alert(isHex("abcdef"));
alert(isHex("0x83464"));
alert(isHex("#273847"));
alert(isHex("This is a test"));
alert(isHex(0x5346));

我故意将返回值保留为字符串,但您所要做的就是删除双引号,然后该函数将返回 TRUE 或 FALSE。

【讨论】:

以上是关于如何检查字符串是不是是有效的十六进制颜色表示?的主要内容,如果未能解决你的问题,请参考以下文章

C++:检查字符串是不是是有效的 MD5 十六进制哈希

十六进制颜色如何工作?

如何将字符串转换为 html 颜色代码哈希?

检查字符串是不是是有效的颜色表示

谁知道一些颜色用十六进制怎么表示?

十六进制颜色如何工作?