Bagaimana cara memeriksa apakah sebuah string adalah representasi warna hex yang valid?

120

Sebagai contoh:

AA33FF = warna hex yang valid

Z34FF9 = warna hex tidak valid (memiliki Z di dalamnya)

AA33FF11 = warna hex tidak valid (memiliki karakter tambahan)

Alex
sumber
10
bergantung pada konteksnya, yang terakhir bisa menjadi warna yang valid, jika menyertakan alfa dalam AARRGGBBformat.
J.Holmes

Jawaban:

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

Untuk menguraikan:

^ ->cocok memulai
# ->hash
[0-9A-F] ->bilangan bulat apa pun dari 0 hingga 9 dan huruf apa pun dari A hingga F
{6} ->grup sebelumnya muncul tepat 6 kali
$ ->cocok dan akhiri
i ->abaikan kasus

Jika Anda memerlukan dukungan untuk kode HEX 3 karakter, gunakan yang berikut ini:

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

Satu-satunya perbedaan di sini adalah itu

 [0-9A-F]{6}

diganti dengan

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

Artinya, alih-alih mencocokkan persis 6 karakter, ini akan cocok persis dengan 3 karakter, tetapi 1 atau 2 kali. Mengizinkan ABCdan AABBCC, tetapi tidakABCD

Royi Namir
sumber
18
Menurut definisi, ini benar, tetapi kode dengan panjang 3 juga valid untuk interpretasi browser. color: #f00;akan diinterpretasikan sebagai merah (# ff0000) juga.
Smamatti
13
atau bentuk lain:/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test("#f00")
J.Holmes
8
Saya juga akan menambahkan /^#([0-9a-f]{3}){1,2}$/ike dalam campuran.
MasterAM
1
@AndresSepar /^#[0-9A-F]{3,6}$/i.test('#aabb')juga lolos, tetapi #aabbbukan warna hex yang valid.
Roman Boiko
3
var isOk = /^#([A-Fa-f0-9]{6}i>[A-Fa-f0-9]{3})$/i.test('#aabbcc '); @RomanBoiko ini benar! Terima kasih!
Andres Separ
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

Jawaban ini digunakan untuk membuang positif palsu karena alih-alih Number('0x' + hex), itu digunakan parseInt(hex, 16).
parseInt()akan mengurai dari awal string hingga mencapai karakter yang tidak termasuk dalam radix ( 16). Artinya, ia dapat mengurai string seperti 'AAXXCC', karena dimulai dengan 'AA'.

Number(), di sisi lain, hanya akan mengurai jika seluruh string cocok dengan radix. Sekarang, Number()tidak mengambil parameter radix, tapi untungnya, Anda bisa mengawali literal angka untuk mendapatkan angka di jari-jari lain.

Berikut tabel klarifikasi:

╭─────────────┬────────────┬────────┬───────────────────╮
 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')    
╰─────────────┴────────────┴────────┴───────────────────╯
fflorent
sumber
6
+1 bcs jauh lebih baik untuk dibaca dan lebih cepat untuk dipahami daripada regex
Chris
10
@Chris 'karena' juga jauh lebih baik untuk dibaca dan lebih cepat untuk dipahami daripada 'bcs' ;-)
Chris
1
@ Chris: Saya sudah terbiasa dengan 'bcs' karena saya tidak membuat perbedaan. lagian komentar saya dimaksudkan sebagai pujian jadi berbahagialah.
Chris
12
Ini salah: parseInt ('abcZab', 16) akan mengeluarkan nomor dan lulus tes
Salvador Dali
1
@fflorent Karena parseIntakan mengambil "abcZab", menemukan yang "Z"tidak valid (untuk radix 16), dan mengabaikannya dan apa pun setelahnya. Ini kemudian mengambil awal "abc"dan mengubahnya menjadi 2748(yang juga merupakan hasil dari parseInt("abcZab", 16), membuktikan bahwa logika terjadi). Sesuai namanya, parseInt parsing string. Sama seperti jika Anda mengurai angka dengan unit di atasnya dengan akar 10 parseInt("10px", 10), Anda akan mendapatkan 10. Anda dapat melihatnya dijelaskan di sini: es5.github.io/#x15.1.2.2 (langkah 11)
Ian
8

Ini bisa menjadi masalah yang rumit. Setelah beberapa kali mencoba, saya menemukan solusi yang cukup bersih. Biarkan alis yang bekerja untuk Anda.

Langkah 1: Buat div dengan gaya batas disetel ke tidak ada. Div dapat diposisikan di luar layar atau bisa juga div apa pun di halaman Anda yang tidak menggunakan batas.

Langkah 2: Atur warna perbatasan menjadi string kosong. Kode tersebut mungkin terlihat seperti ini:

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

Langkah 3: Atur warna perbatasan ke warna yang tidak Anda yakini.

e.style.borderColor=testcol;

Langkah 4: Periksa apakah warnanya benar-benar berubah. Jika testcol tidak valid, tidak akan terjadi perubahan.

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

Langkah 5: Bersihkan sendiri dengan mengatur warna kembali ke string kosong.

e.style.borderColor="";

Div:

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

Sekarang fungsi 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;
}

Dalam kasus ini, fungsi mengembalikan jawaban benar / salah untuk pertanyaan, opsi lainnya adalah mengembalikan nilai warna yang valid. Nilai warna asli Anda, nilai dari borderColor atau string kosong menggantikan warna yang tidak valid.

Terry Prothero
sumber
IMO, ini sama sekali bukan solusi yang bersih
Gust van de Wal
5

Jika Anda mencoba menggunakannya dalam HTML Coba gunakan pola ini Secara Langsung:

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

Suka

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

Ini akan memberikan validasi untuk mencocokkan format yang diminta.

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

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

Catatan: Ini membutuhkan jQuery

Ini berfungsi untuk SEMUA jenis warna bukan hanya nilai hex. Itu juga tidak menambahkan elemen yang tidak perlu ke pohon DOM.

Dustin Poissant
sumber
Bagus dan mudah dan bekerja dengan sangat baik. Secara pribadi saya menambahkan if (hexString.indexOf ('#') == -1) {return false; } untuk memeriksa hash sebagai pemeriksaan dasar bahwa warna adalah nilai hex
365SplendidSuns
1

Jika Anda memerlukan fungsi untuk memberi tahu Anda apakah suatu warna valid, Anda mungkin juga membuatnya memberikan sesuatu yang berguna - nilai yang dihitung dari warna tersebut - dan mengembalikan null jika warna tersebut bukan warna yang valid. Inilah tusukan saya pada fungsi (Chrome54 & MSIE11) yang kompatibel untuk mendapatkan nilai RGBA dari "warna" dalam format apa pun - baik itu 'hijau', atau '#FFF', atau '# 89abcd', atau 'rgb (0,0,128) ', atau' 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;
}
Sempoa
sumber
0

Tambahkan pemeriksaan panjang untuk memastikan Anda tidak mendapatkan hasil positif palsu

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;

}

rotato poti
sumber