Come verificare se una stringa è una rappresentazione di colore esadecimale valida?


120

Per esempio:

AA33FF = colore esadecimale valido

Z34FF9 = colore esadecimale non valido (contiene Z)

AA33FF11 = colore esadecimale non valido (contiene caratteri extra)


10
a seconda del contesto, l'ultimo potrebbe essere un colore valido, se include il AARRGGBBformato alfa .
J. Holmes

Risposte:


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

Elaborare:

^ ->corrisponde all'inizio di
# ->un hash
[0-9A-F] ->qualsiasi numero intero da 0 a 9 e qualsiasi lettera da A a F
{6} ->il gruppo precedente appare esattamente 6 volte
$ ->corrisponde alla fine
i -> ignora le maiuscole e le minuscole

Se hai bisogno di supporto per codici HEX a 3 caratteri, utilizza quanto segue:

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

L'unica differenza qui è quella

 [0-9A-F]{6}

è sostituito con

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

Ciò significa che invece di corrispondere esattamente a 6 caratteri, corrisponderà esattamente a 3 caratteri, ma 1 o 2 volte. Consentire ABCe AABBCC, ma nonABCD


18
Per definizione questo è corretto, ma i codici con una lunghezza di 3 sono validi anche per l'interpretazione del browser. color: #f00;verrà interpretato anche come rosso (# ff0000).
Smamatti

13
o un'altra forma:/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test("#f00")
J. Holmes

8
Aggiungerei anche /^#([0-9a-f]{3}){1,2}$/ial mix.
MasterAM

1
Anche @AndresSepar /^#[0-9A-F]{3,6}$/i.test('#aabb')passa, ma #aabbnon è un colore esadecimale valido.
Roman Boiko

3
var isOk = /^#([A-Fa-f0-9”{6}|[A-Fa-f0-9”{3})$/i.test('#aabbcc '); @RomanBoiko questo è giusto! Grazie!
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

Questa risposta generava falsi positivi perché invece di Number('0x' + hex), usava parseInt(hex, 16).
parseInt()analizzerà dall'inizio della stringa fino a raggiungere un carattere che non è incluso in radix ( 16). Ciò significa che potrebbe analizzare stringhe come "AAXXCC", perché inizia con "AA".

Number(), d'altra parte, analizzerà solo se l'intera stringa corrisponde alla radice. Adesso,Number() non accetta un parametro di base, ma fortunatamente puoi aggiungere un prefisso a letterali numerici per ottenere un numero in altri raggi.

Ecco una tabella per chiarimenti:

╭─────────────┬────────────┬────────┬───────────────────╮
 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 molto meglio da leggere e più veloce da capire di una regex
Chris

10
@Chris "perché" è anche molto meglio da leggere e più veloce da capire rispetto a "bcs" ;-)
Chris

1
@ Chris: mi sono così abituato a "bcs" per me non fa differenza. comunque il mio commento è stato inteso come un complimento quindi sii felice.
Chris,

12
Questo è sbagliato: parseInt ('abcZab', 16) produrrà il numero e supererà il test
Salvador Dali

1
@fflorent Perché parseIntprenderà "abcZab", troverà che "Z"non è valido (per la radice 16) e lo ignorerà e qualsiasi cosa dopo. Quindi prende l'inizio "abc"e lo converte in 2748(che è anche il risultato di parseInt("abcZab", 16), dimostrando che è la logica che sta accadendo). Come suggerisce il nome, parseInt analizza una stringa. Proprio come se stessi analizzando un numero con unità su di esso con una radice di 10, tipo parseInt("10px", 10), otterresti 10. Puoi vederlo descritto qui: es5.github.io/#x15.1.2.2 (passaggio 11)
Ian

8

Questo può essere un problema complicato. Dopo diversi tentativi ho trovato una soluzione abbastanza pulita. Lascia che sia il browser a fare il lavoro per te.

Passaggio 1: crea un div con lo stile del bordo impostato su nessuno. Il div può essere posizionato fuori dallo schermo o può essere qualsiasi div sulla pagina che non utilizza i bordi.

Passaggio 2: imposta il colore del bordo su una stringa vuota. Il codice potrebbe essere simile a questo:

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

Passaggio 3: imposta il colore del bordo sul colore di cui non sei sicuro.

e.style.borderColor=testcol;

Passaggio 4: controlla se il colore è stato effettivamente cambiato. Se testcol non è valido, non si verificherà alcuna modifica.

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

Passaggio 5: ripulisci dopo te stesso impostando il colore su una stringa vuota.

e.style.borderColor="";

Il Div:

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

Ora la funzione 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;
}

In questo caso, la funzione restituisce una risposta vero / falso alla domanda, l'altra opzione è che restituisca un valore di colore valido. Il valore del colore originale, il valore di borderColor o una stringa vuota al posto di colori non validi.


IMO, questa non è affatto una soluzione pulita
Gust van de Wal

5

Se stai cercando di usarlo in HTML, prova a usare questo modello direttamente:

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

piace

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

Fornirà una convalida per abbinare il formato richiesto.


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

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

Nota: questo richiede jQuery

Questo funziona per TUTTI i tipi di colore non solo per i valori esadecimali. Inoltre non aggiunge elementi non necessari all'albero DOM.


Bello e facile e funziona molto bene. Personalmente ho aggiunto if (hexString.indexOf ('#') == -1) {return false; } per verificare la presenza di un hash come controllo rudimentale che il colore fosse un valore esadecimale
365SplendidSuns

1

Se hai bisogno di una funzione che ti dica se un colore è valido, potresti anche farti dare qualcosa di utile - i valori calcolati di quel colore - e restituire null quando non è un colore valido. Ecco il mio tentativo di una funzione compatibile (Chrome54 e MSIE11) per ottenere i valori RGBA di un "colore" in uno qualsiasi dei formati: "verde", "#FFF" o "# 89abcd" o "rgb (0,0,128) "o" 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

Aggiungi un controllo della lunghezza per assicurarti di non ottenere un falso positivo

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;

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.