如何从包含线性渐变定义的字符串中提取色标值?
How does one extract the color-stop values from a string which contains the definition of a linear gradient?
我有一个包含线性渐变定义的字符串...
linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))
...我需要将两个色标值分别分配给一个变量,就像下一个伪代码所示...
const color1 = "rgba(243,231,231,1)";
const color2 = "rgba(12,0,0,0.48)";
只提取数字也可以,我只需要一些可以使用的东西。
问题是,我不能只计算字符和子字符串,因为我的线性渐变字符串值是动态的并且长度可能会改变,有什么想法吗?
您可以使用 String#match
.
let str = "linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))";
let res = str.match(/rgba\(.*?\)/g);
console.log(res);
正则表达式解释:
如果您需要同时支持 rgb
和 rgba
,请使用:
str.match(/rgba?\(.*?\)/g);
我会使用 regexp
https://regex101.com/r/MCdePv/1/
const str = "linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))";
const re = /(rgba?\(.*?\))/g; // find either rgb or rgba
const [color1, color2] = str.match(re);
console.log(color1, color2);
到目前为止所有的方法确实涵盖了仅提取两个并且仅基于 rgb
/rgba
color-stop 一个渐变值。但是关于如何表达线性 css 梯度还有更多有效的变体......例如...
-webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));
-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55)
-o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ;
linear-gradient(135deg , red, red 60%, blue) ;
linear-gradient(yellow, blue 20%, #0f0);
linear-gradient( to left top, blue, green 40%, red );
linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ;
linear-gradient(to bottom right , red, rgba(255, 0, 0, 0));
linear-gradient(right top to left bottom, red, rgb(255, 0, 0));
因此,通用方法的基础必须识别任何梯度定义的 color-stop 的开始。
这意味着 trim
ming a gradient string-value one has to strip off all the unnecessary information except for the clean list of color-stop values. A (kind of validating) regular expression which features a(n optional) positive lookbehind in order to reflect the css-specification of linear gradients utilized by split
确实实现了从左侧剥离...
/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/
... 而 replace
将使用一个相当简单的正则表达式 ... /\s*\)\s*;*$/
... 来从右边去除不必要的字符 ...
console.log([
' -webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));',
'-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55) ',
' -o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ; ',
'linear-gradient(135deg , red, red 60%, blue) ;',
' linear-gradient(yellow, blue 20%, #0f0);',
' linear-gradient( to left top, blue, green 40%, red ); ',
' linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ; ',
' linear-gradient(to bottom right , red, rgba(255, 0, 0, 0)); ',
'linear-gradient(right top to left bottom, red, rgb(255, 0, 0));',
].map(str => str
.trim()
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
.replace((/\s*\)\s*;*$/), '')
));
.as-console-wrapper { min-height: 100%!important; top: 0; }
以上示例的日志记录为每个线性渐变定义显示了一个干净的 color-stop only 字符串。
更复杂的部分是如何正确地 distinguish/separate 颜色停止值的每个可能变体。该规范再次提供帮助。值的拆分可以发生在每个逗号字符后跟一个非数字字符。
像这样的正则表达式.../,(?=\D)/
... which features a positive lookahead 已经完成了这项工作。
但是为了完成这项任务,首先需要去除每个逗号字符周围的所有前导和尾随白色space。最后,可以通过在每个出现的逗号字符之前再次插入一个 space 来 美化 每个颜色停止值。
最终的通用方法,它从线性 css 梯度定义中提取所有色标值的列表,可能看起来类似于以下实现 ...
function getLinearGradientColorStopValues(str) {
return str
.trim()
// strip off left side.
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
// strip off right side.
.replace((/\s*\)\s*;*$/), '')
// strip any whitespace (sequence) before and after each comma.
.replace((/\s*,\s*/g), ',')
// split color-stop values at each comma which is followed by a non digit character.
.split(/,(?=\D)/)
// prettify/normalize each color stop value for better readability.
.map(item => item.replace((/,/g), ', '));
}
console.log([
' -webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));',
'-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55) ',
' -o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ; ',
'linear-gradient(135deg , red, red 60%, blue) ;',
' linear-gradient(yellow, blue 20%, #0f0);',
' linear-gradient( to left top, blue, green 40%, red ); ',
' linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ; ',
' linear-gradient(to bottom right , red, rgba(255, 0, 0, 0)); ',
'linear-gradient(right top to left bottom, red, rgb(255, 0, 0));',
].map(getLinearGradientColorStopValues));
.as-console-wrapper { min-height: 100%!important; top: 0; }
OP 的 example/task 然后就这样解决了 ...
function getLinearGradientColorStopValues(str) {
return str
.trim()
// strip off left side.
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
// strip off right side.
.replace((/\s*\)\s*;*$/), '')
// strip any whitespace (sequence) before and after each comma.
.replace((/\s*,\s*/g), ',')
// split color-stop values at each comma which is followed by a non digit character.
.split(/,(?=\D)/)
// prettify/normalize each color stop value for better readability.
.map(item => item.replace((/,/g), ', '));
}
const [
colorstop1,
colorstop2,
] = getLinearGradientColorStopValues(
"linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))"
);
console.log({ colorstop1, colorstop2 });
.as-console-wrapper { min-height: 100%!important; top: 0; }
我有一个包含线性渐变定义的字符串...
linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))
...我需要将两个色标值分别分配给一个变量,就像下一个伪代码所示...
const color1 = "rgba(243,231,231,1)";
const color2 = "rgba(12,0,0,0.48)";
只提取数字也可以,我只需要一些可以使用的东西。
问题是,我不能只计算字符和子字符串,因为我的线性渐变字符串值是动态的并且长度可能会改变,有什么想法吗?
您可以使用 String#match
.
let str = "linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))";
let res = str.match(/rgba\(.*?\)/g);
console.log(res);
正则表达式解释:
如果您需要同时支持 rgb
和 rgba
,请使用:
str.match(/rgba?\(.*?\)/g);
我会使用 regexp
https://regex101.com/r/MCdePv/1/
const str = "linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))";
const re = /(rgba?\(.*?\))/g; // find either rgb or rgba
const [color1, color2] = str.match(re);
console.log(color1, color2);
到目前为止所有的方法确实涵盖了仅提取两个并且仅基于 rgb
/rgba
color-stop 一个渐变值。但是关于如何表达线性 css 梯度还有更多有效的变体......例如...
-webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));
-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55)
-o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ;
linear-gradient(135deg , red, red 60%, blue) ;
linear-gradient(yellow, blue 20%, #0f0);
linear-gradient( to left top, blue, green 40%, red );
linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ;
linear-gradient(to bottom right , red, rgba(255, 0, 0, 0));
linear-gradient(right top to left bottom, red, rgb(255, 0, 0));
因此,通用方法的基础必须识别任何梯度定义的 color-stop 的开始。
这意味着 trim
ming a gradient string-value one has to strip off all the unnecessary information except for the clean list of color-stop values. A (kind of validating) regular expression which features a(n optional) positive lookbehind in order to reflect the css-specification of linear gradients utilized by split
确实实现了从左侧剥离...
/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/
... 而 replace
将使用一个相当简单的正则表达式 ... /\s*\)\s*;*$/
... 来从右边去除不必要的字符 ...
console.log([
' -webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));',
'-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55) ',
' -o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ; ',
'linear-gradient(135deg , red, red 60%, blue) ;',
' linear-gradient(yellow, blue 20%, #0f0);',
' linear-gradient( to left top, blue, green 40%, red ); ',
' linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ; ',
' linear-gradient(to bottom right , red, rgba(255, 0, 0, 0)); ',
'linear-gradient(right top to left bottom, red, rgb(255, 0, 0));',
].map(str => str
.trim()
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
.replace((/\s*\)\s*;*$/), '')
));
.as-console-wrapper { min-height: 100%!important; top: 0; }
以上示例的日志记录为每个线性渐变定义显示了一个干净的 color-stop only 字符串。
更复杂的部分是如何正确地 distinguish/separate 颜色停止值的每个可能变体。该规范再次提供帮助。值的拆分可以发生在每个逗号字符后跟一个非数字字符。
像这样的正则表达式.../,(?=\D)/
... which features a positive lookahead 已经完成了这项工作。
但是为了完成这项任务,首先需要去除每个逗号字符周围的所有前导和尾随白色space。最后,可以通过在每个出现的逗号字符之前再次插入一个 space 来 美化 每个颜色停止值。
最终的通用方法,它从线性 css 梯度定义中提取所有色标值的列表,可能看起来类似于以下实现 ...
function getLinearGradientColorStopValues(str) {
return str
.trim()
// strip off left side.
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
// strip off right side.
.replace((/\s*\)\s*;*$/), '')
// strip any whitespace (sequence) before and after each comma.
.replace((/\s*,\s*/g), ',')
// split color-stop values at each comma which is followed by a non digit character.
.split(/,(?=\D)/)
// prettify/normalize each color stop value for better readability.
.map(item => item.replace((/,/g), ', '));
}
console.log([
' -webkit-linear-gradient(top , rgb(243, 231, 231), rgba(12, 0, 0, 0.48));',
'-moz-linear-gradient(90deg , hsl(0, 80%, 70%), #bada55) ',
' -o-linear-gradient(bottom, hsl(0, 80%, 70%), #bada55) ; ',
'linear-gradient(135deg , red, red 60%, blue) ;',
' linear-gradient(yellow, blue 20%, #0f0);',
' linear-gradient( to left top, blue, green 40%, red ); ',
' linear-gradient(to top left , red, orange, yellow, green, blue, indigo, violet) ; ',
' linear-gradient(to bottom right , red, rgba(255, 0, 0, 0)); ',
'linear-gradient(right top to left bottom, red, rgb(255, 0, 0));',
].map(getLinearGradientColorStopValues));
.as-console-wrapper { min-height: 100%!important; top: 0; }
OP 的 example/task 然后就这样解决了 ...
function getLinearGradientColorStopValues(str) {
return str
.trim()
// strip off left side.
.split(/^(?:-\w+-)*linear-gradient\((?:.*?(?<=top|bottom|left|right|deg)\s*,\s*)*/)[1]
// strip off right side.
.replace((/\s*\)\s*;*$/), '')
// strip any whitespace (sequence) before and after each comma.
.replace((/\s*,\s*/g), ',')
// split color-stop values at each comma which is followed by a non digit character.
.split(/,(?=\D)/)
// prettify/normalize each color stop value for better readability.
.map(item => item.replace((/,/g), ', '));
}
const [
colorstop1,
colorstop2,
] = getLinearGradientColorStopValues(
"linear-gradient(90deg, rgba(243,231,231,1), rgba(12,0,0,0.48))"
);
console.log({ colorstop1, colorstop2 });
.as-console-wrapper { min-height: 100%!important; top: 0; }