如何在数组中保存RGB(A)值?

时间:2018-11-04 00:00:25

标签: php arrays regex rgb rgba

我正在尝试编写一个函数,该函数将采用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 );

但是它感觉很hacky,我找不到选择或不包括alpha的好方法。

感谢您的帮助,如果有一种与preg_match完全不同的方法会更好,那么我很高兴。

4 个答案:

答案 0 :(得分:4)

我的答案不仅会提取您想要的子字符串值,而且还将执行相当高的验证级别(不是100%完美验证)。我从https://stackoverflow.com/a/31245990/2943403修改了模式,以更精确地解决这个问题。我相信您会发现此答案是准确,优雅且直接的。

如果您想剥离/简化图案,可以这样做:(Regex101 Demo
const SECOND = 1000 const MINUTE = SECOND * 60 const HOUR = MINUTE * 60 const DAY = HOUR * 24 const MONTH = DAY * 30 const YEAR = MONTH * 12

代码:(Demo w/ $include_alpha = true)(Demo w/ $include_alpha = false)(Regex101 Demo

~^rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([.\d]+))?\)$~

输出:

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

p.s。如果您想使用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', ) ,则可能对您的模式不太了解。这是您的单线客。 (Demo

preg_split()

答案 1 :(得分:2)

如果您要使用正则表达式解决方案,则为:

->limit(1)

首先匹配$students = Student::with([ 'addresses' => function($query) { $query->limit(1); }, 'visaDetails', 'instituteDetails', 'subAgents', 'staffDetails', 'commissionDetails', 'comments' ])->paginate(16); ,然后匹配可选的rgba?\((\s?\d+),(\s?\d+),(\s?\d+)(?:,\s?(\d+(?:\.\d+)?))?\) 和左边的'rgb',然后创建3个相似的组,匹配可选的白色'a',后跟一个或两个更多parenthes。第四组是可选的,将匹配一个或多个Space,然后可选地跟一个digits和一个或多个digits

颜色将位于索引1、2、3和4(如果有)。

答案 2 :(得分:2)

您可以使用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
)

答案 3 :(得分:0)

经过改进的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类型强制转换为floatint从字符串中删除多余字符的事实,从字符串中提取数字:

function rgb_array($color, $include_alpha = true)
{
    $array = array_map('floatval', explode(',', $color));
    $array[] = 1;

    return array_slice($array, 0, 3 + $include_alpha);
}