如何将 RGB(A) 值保存在数组中?
How to save RGB(A) values in an array?
我正在尝试编写一个函数,它将采用 RGB(A) 颜色并将其值保存在一个数组中,并提供一个选项来排除 alpha 值。我无法弄清楚如何编写与输入匹配的正则表达式,但我认为我正在寻找这样的东西:
function rgb_array( $color, $include_alpha = true ) {
$pattern = 'what goes here?';
$color = preg_match( $pattern, $color, $matches);
if ( $include_alpha == true && ! empty( $matches[4] ) ) {
$color = array( $matches[1], $matches[2], $matches[3], $matches[4] );
} else {
$color = array( $matches[1], $matches[2], $matches[3] );
}
return $color;
}
我希望能够为它提供任何有效形式的 rgb/rgba:
rgb(0,0,0)
rgb(00,00,00)
rgb(0, 0, 0)
rgb(00, 00, 00)
rgba(0,0,0,0.5)
rgba(255, 255, 255, 1)
etc...
并让它生成一个数组:
[0] => '00', // red
[1] => '00', // green
[2] => '00', // blue
[3] => '1' // alpha only included if available and desired.
目前我可以通过 str_replace
:
$color = 'rgb(12, 14, 85)';
$remove = array( 'rgb', 'a', '(', ')', ' ' );
$color = str_replace( $remove, '', $color );
$color = explode( ',', $color );
但感觉很老套,我找不到一个好方法来选择性地 include/exclude alpha。
感谢您的帮助,如果有与 preg_match
完全不同的方法会更好,我洗耳恭听。
改进了一点explode
解决方案:
function rgb_array($color, $include_alpha = true)
{
$color = trim($color, 'rgba()'); # "rgba(255, 255, 255, 1)" => "255, 255, 255, 1"
$color = str_replace(' ', '', $color); # "255, 255, 255, 1" => "255,255,255,1"
$color = explode(',', $color); # "255,255,255,1" => ["255", "255", "255", "1"]
$color[] = 1; # add extra value to be sure that all parsed colors have transparency
return array_slice($color, 0, 3 + $include_alpha); # length is 3 or 4, depends on $include_alpha value
}
您还可以从字符串中提取数字,因为内置 PHP 类型转换为 float
和 int
会从字符串中删除多余的字符:
function rgb_array($color, $include_alpha = true)
{
$array = array_map('floatval', explode(',', $color));
$array[] = 1;
return array_slice($array, 0, 3 + $include_alpha);
}
如果你想要正则表达式解决方案,这里是:
rgba?\((\s?\d+),(\s?\d+),(\s?\d+)(?:,\s?(\d+(?:\.\d+)?))?\)
它在开始时匹配 'rgb'
,然后是一个可选的 'a'
和一个左边的 parenthes
,然后它创建 3 个相似的组,匹配一个可选的白色 Space
,然后是一个或多个 digits
。第四个组是可选的,将匹配一个或多个 digits
,可选地后跟一个 dot
,以及一个或多个 digits
。
颜色将位于索引 1、2、3 和 4(如果可用)。
您可以使用 preg_split
将字符串拆分为其组成部分。正则表达式在前导 rgba(
、,
或尾随 )
之一处拆分字符串。 PREG_SPLIT_NO_EMPTY
标志用于避免输出数组中出现空白值。
$strings = array('rgb(0,0,0)',
'rgb(00,00,00)',
'rgb(0, 0, 0)',
'rgb(00, 00, 00)',
'rgba(0,0,0,0.5)',
'rgba(255, 255, 255, 1)');
foreach ($strings as $string) {
print_r(preg_split('/rgba?\(\s*|\s*,\s*|\s*\)/', $string, -1, PREG_SPLIT_NO_EMPTY));
}
输出:
Array
(
[0] => 0
[1] => 0
[2] => 0
)
Array
(
[0] => 00
[1] => 00
[2] => 00
)
Array
(
[0] => 0
[1] => 0
[2] => 0
)
Array
(
[0] => 00
[1] => 00
[2] => 00
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0.5
)
Array
(
[0] => 255
[1] => 255
[2] => 255
[3] => 1
)
我的答案不仅会提取您想要的子字符串值,还会执行相当高级别的验证(不是 100% 完美验证)。我修改了 的模式以更准确地解决这个问题。我相信您会发现这个答案是准确、优雅和直接的。
如果你想剥离/简化模式,这样做:(Regex101 Demo)
~^rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([.\d]+))?\)$~
代码:(Demo w/ $include_alpha = true) (Demo w/ $include_alpha = false) (Regex101 Demo)
function rgb_array($color, $include_alpha = true) {
$pattern = '~^rgba?\((25[0-5]|2[0-4]\d|1\d{2}|\d\d?)\s*,\s*(25[0-5]|2[0-4]\d|1\d{2}|\d\d?)\s*,\s*(25[0-5]|2[0-4]\d|1\d{2}|\d\d?)\s*(?:,\s*([01]\.?\d*?))?\)$~';
if (!preg_match($pattern, $color, $matches)) {
return []; // disqualified / no match
}
return array_slice($matches, 1, $include_alpha ? 4 : 3);
}
$strings = [
'rgb(0,0,0)',
'rgb(00,00,00)',
'rgb(0, 0, 0)',
'donkey eggs',
'rgb(00, 00, 00)',
'rgba(0,0,0,0.5)',
'rgba(255, 255, 255, 1)'
];
foreach ($strings as $string) {
echo "Process: $string\n";
var_export(rgb_array($string));
echo "\n";
}
输出:
Process: rgb(0,0,0)
array (
0 => '0',
1 => '0',
2 => '0',
)
Process: rgb(00,00,00)
array (
0 => '00',
1 => '00',
2 => '00',
)
Process: rgb(0, 0, 0)
array (
0 => '0',
1 => '0',
2 => '0',
)
Process: donkey eggs
array (
)
Process: rgb(00, 00, 00)
array (
0 => '00',
1 => '00',
2 => '00',
)
Process: rgba(0,0,0,0.5)
array (
0 => '0',
1 => '0',
2 => '0',
3 => '0.5',
)
Process: rgba(255, 255, 255, 1)
array (
0 => '255',
1 => '255',
2 => '255',
3 => '1',
)
p.s。如果你想使用 preg_split()
你可以不那么具体地描述你的模式。这是给你的单线。 (Demo)
function rgb_array($color, $include_alpha = true) {
return array_slice(preg_split('~[^\d.]+~', $color, -1, PREG_SPLIT_NO_EMPTY), 0, $include_alpha + 3);
}
我正在尝试编写一个函数,它将采用 RGB(A) 颜色并将其值保存在一个数组中,并提供一个选项来排除 alpha 值。我无法弄清楚如何编写与输入匹配的正则表达式,但我认为我正在寻找这样的东西:
function rgb_array( $color, $include_alpha = true ) {
$pattern = 'what goes here?';
$color = preg_match( $pattern, $color, $matches);
if ( $include_alpha == true && ! empty( $matches[4] ) ) {
$color = array( $matches[1], $matches[2], $matches[3], $matches[4] );
} else {
$color = array( $matches[1], $matches[2], $matches[3] );
}
return $color;
}
我希望能够为它提供任何有效形式的 rgb/rgba:
rgb(0,0,0)
rgb(00,00,00)
rgb(0, 0, 0)
rgb(00, 00, 00)
rgba(0,0,0,0.5)
rgba(255, 255, 255, 1)
etc...
并让它生成一个数组:
[0] => '00', // red
[1] => '00', // green
[2] => '00', // blue
[3] => '1' // alpha only included if available and desired.
目前我可以通过 str_replace
:
$color = 'rgb(12, 14, 85)';
$remove = array( 'rgb', 'a', '(', ')', ' ' );
$color = str_replace( $remove, '', $color );
$color = explode( ',', $color );
但感觉很老套,我找不到一个好方法来选择性地 include/exclude alpha。
感谢您的帮助,如果有与 preg_match
完全不同的方法会更好,我洗耳恭听。
改进了一点explode
解决方案:
function rgb_array($color, $include_alpha = true)
{
$color = trim($color, 'rgba()'); # "rgba(255, 255, 255, 1)" => "255, 255, 255, 1"
$color = str_replace(' ', '', $color); # "255, 255, 255, 1" => "255,255,255,1"
$color = explode(',', $color); # "255,255,255,1" => ["255", "255", "255", "1"]
$color[] = 1; # add extra value to be sure that all parsed colors have transparency
return array_slice($color, 0, 3 + $include_alpha); # length is 3 or 4, depends on $include_alpha value
}
您还可以从字符串中提取数字,因为内置 PHP 类型转换为 float
和 int
会从字符串中删除多余的字符:
function rgb_array($color, $include_alpha = true)
{
$array = array_map('floatval', explode(',', $color));
$array[] = 1;
return array_slice($array, 0, 3 + $include_alpha);
}
如果你想要正则表达式解决方案,这里是:
rgba?\((\s?\d+),(\s?\d+),(\s?\d+)(?:,\s?(\d+(?:\.\d+)?))?\)
它在开始时匹配 'rgb'
,然后是一个可选的 'a'
和一个左边的 parenthes
,然后它创建 3 个相似的组,匹配一个可选的白色 Space
,然后是一个或多个 digits
。第四个组是可选的,将匹配一个或多个 digits
,可选地后跟一个 dot
,以及一个或多个 digits
。
颜色将位于索引 1、2、3 和 4(如果可用)。
您可以使用 preg_split
将字符串拆分为其组成部分。正则表达式在前导 rgba(
、,
或尾随 )
之一处拆分字符串。 PREG_SPLIT_NO_EMPTY
标志用于避免输出数组中出现空白值。
$strings = array('rgb(0,0,0)',
'rgb(00,00,00)',
'rgb(0, 0, 0)',
'rgb(00, 00, 00)',
'rgba(0,0,0,0.5)',
'rgba(255, 255, 255, 1)');
foreach ($strings as $string) {
print_r(preg_split('/rgba?\(\s*|\s*,\s*|\s*\)/', $string, -1, PREG_SPLIT_NO_EMPTY));
}
输出:
Array
(
[0] => 0
[1] => 0
[2] => 0
)
Array
(
[0] => 00
[1] => 00
[2] => 00
)
Array
(
[0] => 0
[1] => 0
[2] => 0
)
Array
(
[0] => 00
[1] => 00
[2] => 00
)
Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0.5
)
Array
(
[0] => 255
[1] => 255
[2] => 255
[3] => 1
)
我的答案不仅会提取您想要的子字符串值,还会执行相当高级别的验证(不是 100% 完美验证)。我修改了 的模式以更准确地解决这个问题。我相信您会发现这个答案是准确、优雅和直接的。
如果你想剥离/简化模式,这样做:(Regex101 Demo)
~^rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([.\d]+))?\)$~
代码:(Demo w/ $include_alpha = true) (Demo w/ $include_alpha = false) (Regex101 Demo)
function rgb_array($color, $include_alpha = true) {
$pattern = '~^rgba?\((25[0-5]|2[0-4]\d|1\d{2}|\d\d?)\s*,\s*(25[0-5]|2[0-4]\d|1\d{2}|\d\d?)\s*,\s*(25[0-5]|2[0-4]\d|1\d{2}|\d\d?)\s*(?:,\s*([01]\.?\d*?))?\)$~';
if (!preg_match($pattern, $color, $matches)) {
return []; // disqualified / no match
}
return array_slice($matches, 1, $include_alpha ? 4 : 3);
}
$strings = [
'rgb(0,0,0)',
'rgb(00,00,00)',
'rgb(0, 0, 0)',
'donkey eggs',
'rgb(00, 00, 00)',
'rgba(0,0,0,0.5)',
'rgba(255, 255, 255, 1)'
];
foreach ($strings as $string) {
echo "Process: $string\n";
var_export(rgb_array($string));
echo "\n";
}
输出:
Process: rgb(0,0,0)
array (
0 => '0',
1 => '0',
2 => '0',
)
Process: rgb(00,00,00)
array (
0 => '00',
1 => '00',
2 => '00',
)
Process: rgb(0, 0, 0)
array (
0 => '0',
1 => '0',
2 => '0',
)
Process: donkey eggs
array (
)
Process: rgb(00, 00, 00)
array (
0 => '00',
1 => '00',
2 => '00',
)
Process: rgba(0,0,0,0.5)
array (
0 => '0',
1 => '0',
2 => '0',
3 => '0.5',
)
Process: rgba(255, 255, 255, 1)
array (
0 => '255',
1 => '255',
2 => '255',
3 => '1',
)
p.s。如果你想使用 preg_split()
你可以不那么具体地描述你的模式。这是给你的单线。 (Demo)
function rgb_array($color, $include_alpha = true) {
return array_slice(preg_split('~[^\d.]+~', $color, -1, PREG_SPLIT_NO_EMPTY), 0, $include_alpha + 3);
}