Comment vérifier si une chaîne est une représentation de couleur hexadécimale valide?

120

Par exemple:

AA33FF = couleur hexadécimale valide

Z34FF9 = couleur hexadécimale invalide (contient Z)

AA33FF11 = couleur hexadécimale non valide (contient des caractères supplémentaires)

Alex
la source
10
selon le contexte, la dernière peut être une couleur valide, si elle inclut un AARRGGBBformat alpha .
J. Holmes

Réponses:

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

Élaborer:

^ ->match commençant
# ->un hachage
[0-9A-F] ->tout entier de 0 à 9 et toute lettre de A à F
{6} ->le groupe précédent apparaît exactement 6 fois
$ ->match end
i ->ignorer la casse

Si vous avez besoin de la prise en charge des codes HEX à 3 caractères, utilisez ce qui suit:

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

La seule différence ici est que

 [0-9A-F]{6}

est remplacé par

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

Cela signifie qu'au lieu de correspondre exactement à 6 caractères, il correspondra exactement à 3 caractères, mais 1 ou 2 fois. Permettre ABCet AABBCC, mais pasABCD

Royi Namir
la source
18
Par définition, c'est correct, mais les codes d'une longueur de 3 sont également valides pour l'interprétation du navigateur. color: #f00;sera également interprété comme rouge (# ff0000).
Smamatti
13
ou une autre forme:/^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test("#f00")
J. Holmes
8
J'ajouterais également /^#([0-9a-f]{3}){1,2}$/iau mélange.
MasterAM
1
@AndresSepar /^#[0-9A-F]{3,6}$/i.test('#aabb')passe également, mais #aabbn'est pas une couleur hexadécimale valide.
Roman Boiko
3
var isOk = /^#([A-Fa-f0-9ITED{6}|[A-Fa-f0-9[ ){3})$/i.test('#aabbcc '); @RomanBoiko c'est vrai! Merci!
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

Cette réponse avait l'habitude de lancer de faux positifs car au lieu de Number('0x' + hex)cela, elle était utilisée parseInt(hex, 16).
parseInt()analysera depuis le début de la chaîne jusqu'à ce qu'elle atteigne un caractère qui n'est pas inclus dans la racine ( 16). Cela signifie qu'il pourrait analyser des chaînes comme «AAXXCC», car il commence par «AA».

Number(), d'autre part, analysera uniquement si la chaîne entière correspond à la base. Maintenant, Number()ne prend pas de paramètre de base, mais heureusement, vous pouvez préfixer des littéraux numériques pour obtenir un nombre dans d'autres rayons.

Voici un tableau pour clarification:

╭─────────────┬────────────┬────────┬───────────────────╮
 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
la source
6
+1 bcs beaucoup mieux à lire et plus rapide à comprendre qu'une regex
Chris
10
@Chris 'parce que' est aussi beaucoup mieux à lire et plus rapide à comprendre que 'bcs' ;-)
Chris
1
@Chris: je me suis tellement habitué à «bcs» pour moi ne fait aucune différence. de toute façon mon commentaire était un compliment alors soyez heureux.
Chris
12
C'est faux: parseInt ('abcZab', 16) affichera le numéro et passera le test
Salvador Dali
1
@fflorent Car parseIntprendra "abcZab", trouve que "Z"c'est invalide (pour radix 16), et ignorez-le et tout ce qui suit. Il prend ensuite le début "abc"et le convertit en 2748(ce qui est également le résultat de parseInt("abcZab", 16), prouvant que c'est la logique qui se passe). Comme son nom l'indique, parseInt analyse une chaîne. Tout comme si vous analysiez un nombre avec des unités dessus avec une base de 10, comme parseInt("10px", 10), vous obtiendrez 10. Vous pouvez le voir décrit ici: es5.github.io/#x15.1.2.2 (étape 11)
Ian
8

Cela peut être un problème compliqué. Après plusieurs tentatives, j'ai trouvé une solution assez propre. Laissez le navigateur faire le travail pour vous.

Étape 1: Créez un div avec le style de bordure défini sur aucun. Le div peut être positionné hors de l'écran ou il peut s'agir de n'importe quel div de votre page qui n'utilise pas les bordures.

Étape 2: définissez la couleur de la bordure sur une chaîne vide. Le code pourrait ressembler à ceci:

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

Étape 3: définissez la couleur de la bordure sur la couleur dont vous n'êtes pas sûr.

e.style.borderColor=testcol;

Étape 4: Vérifiez si la couleur a réellement changé. Si testcol n'est pas valide, aucun changement ne se produira.

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

Étape 5: Nettoyez après vous en redéfinissant la couleur sur une chaîne vide.

e.style.borderColor="";

La Div:

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

Maintenant, la fonction 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;
}

Dans ce cas, la fonction renvoie une réponse vrai / faux à la question, l'autre option est de lui faire renvoyer une valeur de couleur valide. Votre valeur de couleur d'origine, la valeur de borderColor ou une chaîne vide à la place de couleurs non valides.

Terry Prothero
la source
OMI, ce n'est pas du tout une solution propre
Gust van de Wal
5

Si vous essayez de l'utiliser en HTML, essayez d'utiliser ce modèle directement:

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

comme

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

Il donnera une validation pour correspondre au format demandé.

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

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

Remarque: cela nécessite jQuery

Cela fonctionne pour TOUS les types de couleurs et pas seulement pour les valeurs hexadécimales. Il n'ajoute pas non plus d' éléments inutiles à l'arborescence DOM.

Dustin Poissant
la source
Nice et facile et fonctionne très bien. Personnellement, j'ai ajouté if (hexString.indexOf ('#') == -1) {return false; } pour vérifier un hachage comme une vérification rudimentaire que la couleur était une valeur hexadécimale
365SplendidSuns
1

Si vous avez besoin d'une fonction pour vous dire si une couleur est valide, vous pouvez aussi bien qu'elle vous donne quelque chose d'utile - les valeurs calculées de cette couleur - et renvoie null quand ce n'est pas une couleur valide. Voici mon essai sur une fonction compatible (Chrome54 et MSIE11) pour obtenir les valeurs RGBA d'une "couleur" dans l'un des formats - que ce soit 'vert', '#FFF', ou '# 89abcd' ou 'rgb (0,0,128) »ou« 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;
}
Abaque
la source
0

Ajoutez une vérification de longueur pour vous assurer que vous n'obtenez pas un faux positif

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
la source