Як перевірити, чи є рядок дійсним шістнадцятковим кольоровим поданням?


120

Наприклад:

AA33FF = дійсний шістнадцятковий колір

Z34FF9 = недійсний шістнадцятковий колір (у ньому Z)

AA33FF11 = недійсний шістнадцятковий колір (має додаткові символи)


10
залежно від контексту, останній може бути дійсним кольором, якщо він включає альфа у AARRGGBBформаті.
Дж. Холмс

Відповіді:


283
/^#[0-9A-F]{6}$/i.test('#AABBCC')

Розробити:

^ ->матч, що починає
# ->хеш,
[0-9A-F] ->будь-яке ціле число від 0 до 9, і будь-яка літера від А до 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 рази. Дозволити ABCі AABBCC, але ніABCD


18
За визначенням це правильно, але коди довжиною 3 також дійсні для інтерпретації браузера. color: #f00;буде також трактуватися як червоний (# ff0000).
Smamatti

13
або інша форма:/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test("#f00")
Дж. Холмс

8
Я також додав /^#([0-9a-f]{3}){1,2}$/iби до суміші.
MasterAM

1
@AndresSepar /^#[0-9A-F]{3,6}$/i.test('#aabb')також проходить, але #aabbце не допустимий шістнадцятковий колір.
Роман Бойко

3
var isOk = /^#( evidenceA-Fa-f0-9 снимки{6}| evidenceA-Fa-f0-9 freed{3})$/i.test('#aabbcc '); @RomanBoiko це правильно! Дякую!
Андрес Сепар

32

// 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

Ця відповідь використовується , щоб кинути помилкові спрацьовування , оскільки замість того Number('0x' + hex), вона використовується parseInt(hex, 16).
parseInt()буде аналізувати з початку рядка, поки не досягне символу, не включеного в radix ( 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')    
╰─────────────┴────────────┴────────┴───────────────────╯

6
+1 bcs набагато краще для читання та швидше зрозуміти, ніж регулярний вираз
Кріс,

10
@Chris 'тому, що' також набагато краще читати і швидше розуміти, ніж 'bcs' ;-)
Кріс

1
@Chris: Я так звик до 'ПК', що для мене не має значення. у будь-якому випадку мій коментар мав на увазі як комплімент, тож будьте щасливі.
Кріс

12
Це неправильно: parseInt ('abcZab', 16) видасть номер і пройде тест
Сальвадор Далі

1
@fflorent Тому що parseIntвізьмеш "abcZab", знайди, що "Z"він недійсний (для radix 16), і ігноруй його та будь-що після нього. Потім він бере початок "abc"і перетворює його в 2748(що також є результатом parseInt("abcZab", 16), доводячи, що це логіка). Як випливає з назви, parseInt розбирає рядок. Так само, якби ви розбирали число з одиницями на ньому з радіусом 10, як parseInt("10px", 10), ви отримаєте 10. Ви можете ознайомитись із описаним тут: es5.github.io/#x15.1.2.2 (крок 11)
Ян

8

Це може бути складною проблемою. Після кількох спроб я придумав досить чисте рішення. Нехай браузер виконує роботу за вас.

Крок 1: Створіть команду div, встановлену для жодного стилю border. Діл може бути розміщений на екрані, або це будь-який 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:

<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, це не менш чисте рішення
Густ ван де Валь,

5

Якщо ви намагаєтесь використовувати його в 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})$" />

Це дасть перевірку на відповідність запитуваному формату.


2
function validColor(color){
  var $div = $("<div>");
  $div.css("border", "1px solid "+color);
  return ($div.css("border-color")!="")
}

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

Примітка. Для цього потрібен jQuery

Це працює для ВСІХ кольорових типів, а не лише шістнадцяткових значень. Він також не додає зайві елементи до дерева DOM.


Приємно і легко і працює дуже добре. Особисто я додав if (hexString.indexOf ('#') == -1) {return false; } перевірити хеш як рудиментарну перевірку, чи колір був шістнадцятковим
365SplendidSuns

1

Якщо вам потрібна функція, яка дозволяє вам повідомити, чи є колір дійсним, ви також можете йому дати щось корисне - обчислені значення цього кольору - і повернути null, коли він не є дійсним кольором. Ось мій показник сумісної функції (Chrome54 & MSIE11), щоб отримати значення RGBA "кольору" у будь-якому з форматів - будь то "зелений", або "#FFF", або "# 89abcd", або "rgb" (0,0128) 'або' 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;
}

0

Додайте перевірку довжини, щоб переконатися, що у вас не виявиться помилкового додатника

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;

}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.