我正在使用SO上建议的当前代码,从"rgb(0, 0, 0)"之类的字符串中获取RGB值,但它也可以是"rgb(0, 0, 0,096)",所以现在我还需要获取alpha值
function getRGB(str) {
var match = str.match(/rgba?((d{1,3}), ?(d{1,3}), ?(d{1,3}))?(?:, ?(d(?:.d?))))?/);
arr = [match[1], match[2], match[3]];
return arr;
}
我在下面尝试了这段代码,但它不起作用
function getRGBA(str) {
var match = str.match(/rgba?((d{1,3}), ?(d{1,3}), ?(d{1,3}), ?(d{1,3}))?(?:, ?(d(?:.d?))))?/);
arr = [match[1], match[2], match[3], match[4]];
return arr;
}
您的原始正则表达式已经允许使用 alpha(有四组数字,中间有逗号,其中第四组是可选的;另请注意,rgba
开头附近的a
是可选的,因为它后面有?
)。您可以通过查看match[4]
来判断您是否获得了 alpha 版本:
function getRGB(str) {
var match = str.match(/rgba?((d{1,3}), ?(d{1,3}), ?(d{1,3}))?(?:, ?(d(?:.d?))))?/);
arr = [match[1], match[2], match[3]];
if (match[4]) { // ***
arr.push(match[4]); // ***
} // ***
return arr;
}
严格来说不是你问的,但正则表达式有几个问题会阻止它可靠地检测字符串:
- 它只允许逗号后的一个空格,但多个空格有效
- 逗号前不允许任何空格
- 在 alpha 部分,它允许
1.
但如果没有.
后面的数字,这是无效
的
其他一些注意事项:
- 该代码依赖于我所说的隐式全局的恐怖,因为它从不声明
arr
。 - 代码不会将值转换为数字。我不知道你是否想这样做,但我认为这是值得注意的。
- 如果字符串与表达式不匹配,该函数将引发错误。也许这就是你想要的,但我想我会把它标记出来。
此表达式可以更好地匹配:
/rgba?((d{1,3})s*,s*(d{1,3})s*,s*(d{1,3})s*(?:)|,s*(d?(?:.d+)?)))/
现场示例:
function num(str) {
str = str.trim();
// Just using + would treat "" as 0
// Using parseFloat would ignore trailing invalid chars
// More: https://stackoverflow.com/questions/28994839/why-does-string-to-number-comparison-work-in-javascript/28994875#28994875
return str === "" ? NaN : +str;
}
function getRGB(str) {
const match = str.match(/rgba?((d{1,3})s*,s*(d{1,3})s*,s*(d{1,3})s*(?:)|,s*(d?(?:.d+)?)))/);
if (!match) {
return null;
}
const arr = [
num(match[1]),
num(match[2]),
num(match[3])
];
if (match[4]) {
arr.push(num(match[4]));
}
return arr;
}
function test(str) {
console.log(str, "=>", JSON.stringify(getRGB(str)))
}
test("rgb(1,2,3,4)"); // [1, 2, 3, 4]
test("rgba(1 , 2, 3, 4)"); // [1, 2, 3, 4]
test("rgba(111 , 22, 33)"); // [111, 22, 33]
test("rgb(111, 22)"); // null (doesn't match)
test("rgb(111, 22 , 33, 1)"); // [111, 22, 33, 1]
test("rgb(111, 22, 33, 1.)"); // null (doesn't match, no digit after .)
test("rgb(111, 22, 33, 1.0)"); // [111, 22, 33, 1]
test("rgb(111, 22, 33, .5)"); // [111, 22, 33, 0.5]
.as-console-wrapper {
max-height: 100% !important;
}
在现代 JavaScript 环境中,我们可以通过使用命名捕获组来简化使用(请参阅num
函数的实时示例以及为什么我使用它而不是+
/Number
或parseFloat
):
function getRGB(str) {
const {groups} = str.match(
/rgba?((?<r>d{1,3})s*,s*(?<g>d{1,3})s*,s*(?<b>d{1,3})s*(?:)|,s*(?<a>d?(?:.d+)?)))/
) ?? {groups: null};
if (!groups) {
return null;
}
const arr = [
num(groups.r),
num(groups.g),
num(groups.b)
];
if (groups.a) {
arr.push(num(groups.a));
}
return arr;
}
现场示例:
function num(str) {
str = str.trim();
// Just using + would treat "" as 0
// Using parseFloat would ignore trailing invalid chars
// More: https://stackoverflow.com/questions/28994839/why-does-string-to-number-comparison-work-in-javascript/28994875#28994875
return str === "" ? NaN : +str;
}
function getRGB(str) {
const {groups} = str.match(
/rgba?((?<r>d{1,3})s*,s*(?<g>d{1,3})s*,s*(?<b>d{1,3})s*(?:)|,s*(?<a>d?(?:.d+)?)))/
) ?? {groups: null};
if (!groups) {
return null;
}
const arr = [
num(groups.r),
num(groups.g),
num(groups.b)
];
if (groups.a) {
arr.push(num(groups.a));
}
return arr;
}
function test(str) {
console.log(str, "=>", JSON.stringify(getRGB(str)))
}
test("rgb(1,2,3,4)"); // [1, 2, 3, 4]
test("rgba(1 , 2, 3, 4)"); // [1, 2, 3, 4]
test("rgba(111 , 22, 33)"); // [111, 22, 33]
test("rgb(111, 22)"); // null (doesn't match)
test("rgb(111, 22 , 33, 1)"); // [111, 22, 33, 1]
test("rgb(111, 22, 33, 1.)"); // null (doesn't match, no digit after .)
test("rgb(111, 22, 33, 1.0)"); // [111, 22, 33, 1]
test("rgb(111, 22, 33, .5)"); // [111, 22, 33, 0.5]
.as-console-wrapper {
max-height: 100% !important;
}