จะตรวจสอบได้อย่างไรว่าสตริงเป็นตัวแทนสีฐานสิบหกที่ถูกต้องหรือไม่?


120

ตัวอย่างเช่น:

AA33FF = สีฐานสิบหกที่ถูกต้อง

Z34FF9 = สีฐานสิบหกไม่ถูกต้อง (มี Z อยู่)

AA33FF11 = สีฐานสิบหกไม่ถูกต้อง (มีอักขระพิเศษ)


10
สีสุดท้ายอาจเป็นสีที่ถูกต้องทั้งนี้ขึ้นอยู่กับบริบทหากมีAARRGGBBรูปแบบอัลฟา
เจโฮล์มส์

คำตอบ:


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

ทำอย่างละเอียด:

^ ->การจับคู่เริ่มต้น
# ->แฮช
[0-9A-F] ->จำนวนเต็มใด ๆ จาก 0 ถึง 9 และตัวอักษรใด ๆ จาก A ถึง F
{6} ->กลุ่มก่อนหน้านี้จะปรากฏตรง 6 ครั้ง
$ ->ตรงกับตัว
i ->พิมพ์เล็กและใหญ่

หากคุณต้องการการสนับสนุนรหัส HEX 3 อักขระให้ใช้สิ่งต่อไปนี้:

/^#([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")
เจโฮล์มส์

9
ฉันจะเพิ่ม/^#([0-9a-f]{3}){1,2}$/iส่วนผสม
MasterAM

1
@AndresSepar /^#[0-9A-F]{3,6}$/i.test('#aabb')ก็ผ่านเช่นกัน แต่#aabbไม่ใช่สีฐานสิบหกที่ถูกต้อง
Roman Boiko

3
var isOk = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/i.test('#aabbcc '); @RomanBoiko นี่ใช่เลย! ขอบคุณ!
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

คำตอบนี้ใช้ในการโยนบวกเท็จเพราะแทนที่จะก็ใช้Number('0x' + hex) จะแยกวิเคราะห์จากจุดเริ่มต้นของสตริงจนกว่าจะถึงอักขระที่ไม่ได้รวมอยู่ในรัศมี ( ) ซึ่งหมายความว่าสามารถแยกวิเคราะห์สตริงเช่น 'AAXXCC' ได้เนื่องจากเริ่มต้นด้วย 'AA'parseInt(hex, 16)
parseInt()16

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 ดีกว่ามากในการอ่านและทำความเข้าใจได้เร็วกว่า regex
คริส

10
@Chris 'เพราะ' ยังอ่านได้ดีกว่าและเข้าใจได้เร็วกว่า 'bcs' ;-)
คริส

1
@ คริส: ฉันคุ้นเคยกับ 'bcs' มากสำหรับฉันไม่ได้สร้างความแตกต่าง อย่างไรก็ตามความคิดเห็นของฉันหมายถึงคำชมเชยดังนั้นจงมีความสุข
คริส

12
สิ่งนี้ผิด: parseInt ('abcZab', 16) จะส่งออกหมายเลขและผ่านการทดสอบ
Salvador Dali

1
@fflorent เนื่องจากparseIntจะใช้เวลา"abcZab"พบว่า"Z"ไม่ถูกต้อง (สำหรับเลขที่ 16) และไม่สนใจมันและอะไรก็ตามหลังจากนั้น จากนั้นจะเริ่มต้น"abc"และแปลงเป็น2748(ซึ่งเป็นผลมาจากการparseInt("abcZab", 16)พิสูจน์ว่าเป็นตรรกะที่เกิดขึ้น) ตามความหมายของชื่อให้parseInt แยกวิเคราะห์สตริง เช่นเดียวกับถ้าคุณแยกจำนวนหน่วยที่มันมีกี่ 10 เช่นเดียวกับที่คุณจะได้รับparseInt("10px", 10) 10คุณสามารถดูคำอธิบายได้ที่นี่: es5.github.io/#x15.1.2.2 (ขั้นตอนที่ 11)
เอียน

8

นี่อาจเป็นปัญหาที่ซับซ้อน หลังจากพยายามหลายครั้งฉันก็หาวิธีแก้ปัญหาที่ค่อนข้างสะอาด ปล่อยให้เบราว์เซอร์ทำงานแทนคุณ

ขั้นตอนที่ 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:

<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 นี่ไม่ใช่วิธีแก้ปัญหาที่สะอาดอย่างน้อยที่สุด
Gust van de Wal

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,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;
}

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;

}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.