挑战是获取字符串值(在JavaScript中)和:
a)确定字符串值是否为有效的颜色表示(3位十六进制,6位十六进制或rgb值)
b)检索有效颜色值(例如3个十六进制数字,3个十六进制数对或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位十六进制值(例如“FFFFFF”):
re = /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/;
对于3位十六进制值(例如“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
}
这些是最有效的正则表达式吗?或者有更好的方法,也许不使用正则表达式?
(致谢:这是解决Stoyan在http://www.phpied.com/rgb-color-parser-in-javascript)在RGB Color Parser代码中发现的无效匹配
答案 0 :(得分:0)
如果任何其他解决方案失败,则应使用IMHO正则表达式。所以这是我的方法:
var color = "(...)";
var fetchedValue;
/**
* @param searchString
* @return string
*/
function getHexValue(searchString) {
var noHash = searchString.replace("#","");
if ((noHash.length !== 6 && noHash.length !== 3) || noHash.match(/[0-9A-Fa-f]/g).length < noHash.length) {
return false;
}
return noHash;
}
/**
* @param searchString
* @return array
*/
function getRGBValue(searchString) {
var ingredients = searchString.match(/\d{,3}/g);
for (var i in ingredients) {
if (parseInt(ingredients[i]) > 255) {
return false;
}
}
return ingredients;
}
if ('#' == color.substring(0, 1)) { // the color is in HEX
fetchedValue = getHexValue(color);
} else {
fetchedValue = getRGBValue(color);
}
答案 1 :(得分: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