2

課題は、(JavaScript で) 文字列値を取得し、次のことを行うことです。

a) 文字列値が有効な色表現 (3 桁の 16 進数、6 桁の 16 進数、または RGB 値) であるかどうかを判断します。

b) 有効な色の値を取得します (例: 3 つの 16 進数、3 つの 16 進数のペア、または 3 つの RGB 値)

c) これをできるだけ効率的に行う。

次の正規表現は機能しますが、できるだけ効率的にする必要があります。

RGB(r,g,b) 一致の場合、r、g および b の値が 0 ~ 255 であることを確認し、r、g、b 一致のみを許可します (たとえば、入力は "255,255,255" または "255, 255, 255" です)または「rgb(255,255,255)」など)

re = /^rgb\(([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]),\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]),\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\)$|^([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]),\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]),\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$/;

6 桁の 16 進数値 (例: "FFFFFF") の場合:

re = /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/;

3 桁の 16 進数値 (例: "FFF") の場合:

re = /^([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/;

これらのそれぞれについて、次を使用します。

result = re.exec(value);
if (result) {
    // process using e.g. result[1], result[2] & result[3] as needed
}

これらはこれを達成するための最も効率的な正規表現ですか? それとも、おそらく正規表現を使用しないより良い方法がありますか?

(クレジット: これは、 http: //www.phpied.com/rgb-color-parser-in-javascript で Stoyan によって RGB カラー パーサー コードで発見された無効な一致を解決しています)

4

2 に答える 2

0

以下は、軽くテストされた、あなたが望むことをするはずです。さらに削減できることは間違いありませんが、それだけの価値があるかどうかはわかりません。コメントを除いた約 15 行のコードです。

forEachのサポートに依存するため、シムするか、for ループに置き換えます。戦略は、入力をトークン化し、ビットを処理することです (パーサーのように):

/* Accept:
**   number triplets: xxx,xxx,xxx
**   rgb values     : rgb(xxx,xxx,xxx)
**   Hex values     : xxxxxx and xxxx
**   prefixed hex   : #xxxxxx and #xxx
*/
function parseColourString(s) {

  // Tokenise input
  var m = s.match(/^\#|^rgb\(|[\d\w]+$|\d{3}/g);

  // Other variables
  var value, values;
  var valid = true, double = false;

  // If no matches, return false
  if (!m) return false;

  // If hex value
  if (m.length < 3) {
    // Get the value
    value = m[m.length-1];

    // Split into parts, either x,x,x or xx,xx,xx
    values = value.length == 3? double = true && value.split('') : value.match(/../g);

    // Convert to decimal values - if #nnn, double up on values 345 => 334455
    values.forEach(function(v,i){values[i] = parseInt(double? ''+v+v : v, 16);});

  // Otherwise it's rgb, get the values
  } else {
    values = m.length == 3? m.slice() : m.slice(1);
  }

  // Check that each value is between 0 and 255 inclusive and return the result
  values.forEach(function(v){valid = valid? v >= 0 && v <= 255 : false;});

  // If string is invalid, return false, otherwise return an array of the values
  return valid && values;
}

console.log(parseColourString('#345fff'));            // [52, 95, 255]
console.log(parseColourString('#a3b'));               // [170, 51, 187]
console.log(parseColourString('#aa33bb'));            // [170, 51, 187]
console.log(parseColourString('a3b3c3'));             // [163, 179, 195]
console.log(parseColourString('rgb(123, 123, 123)')); // ["123", "123", "123"]
console.log(parseColourString('123, 123, 123'));      // ["123", "123", "123"]
console.log(parseColourString('aeiou'));              // false
console.log(parseColourString(''));                   // false
console.log(parseColourString('rgb(123,234,345)'));   // false
于 2013-10-09T23:45:31.030 に答える