缩短颜色字符串的正则表达式

时间:2016-03-15 17:08:08

标签: javascript regex hex rgb

box-shadow计算值或样式规则替换颜色字符串非常喧嚣。找到了一些东西,但我需要更短的东西。

// extract a hex color with a space before or after
// test string "1px 1px #555 inset" OR "1px 1px #555"
var color1 = "1px 1px #555 inset"; // OR "1px 1px #555"
var hex = color1.match(/(\s+\#+([a-f0-9]{6}|[a-f0-9]{3})|\#+([a-f0-9]{6}|[a-f0-9]{3})+\s)/ig);

// also extract a rgb/rgba with a space before or after
var color2 = "rgb(150,160,155) 1px 2px"; // OR "1px 2px rgb(150,160,155) inset"
var rgb = color2.match(/(rgb|rgba)+\([^)]+\)+\s|\s+(rgb|rgba)+\([^)]+\)/g);

正如你所看到的,两者看起来都很长,但它们的工作效果差不多。

更新:根据要求,我将添加更多关于我期望从这个正则表达式的信息。这里是测试用例:

  • 1px 1px #555 - 从此字符串开始,我需要前面带空格的颜色,完全如此' #555'
  • 1px 1px #555 inset - 从这个字符串开始,我需要前后空格的颜色,完全如此' #555 '
  • 1px 1px rgb(150,150, 150) - 从这个字符串开始我需要前面带空格的颜色,就像这样' rgb(150,150, 150)'
  • 1px 1px rgb(150,150, 150) inset - 从这个字符串开始,我需要前后空格的颜色,完全如此' rgb(150,150, 150) '
  • rgb(150,150, 150) 1px 1px - 从这个字符串开始,我需要带有空格的颜色,正好是'rgb(150,150, 150) '

我希望现在很清楚。那么有没有办法缩短它们并检查上面解释的所有内容?

2 个答案:

答案 0 :(得分:2)

您可以将两种模式合并为一种:

// extract a hex color with a space before or after
// test string  OR "1px 1px #555"
var color1 = "1px 1px #555 inset"; // OR "1px 1px #555"
// also extract a rgb/rgba with a space before or after
var color2 = "rgb(150,160,155) 1px 2px"; // OR "1px 2px rgb(150,160,155)"
var color3 = "rgb(0, 0, 0) 15px 15px 6px 0px inset";
var p = /(\s?(?:#(?:[\da-f]{3}){1,2}|rgba?\(\d{1,3},\s*\d{1,3},\s*\d{1,3}\))\s?)/gi;
var rgb1 = color1.match(p);
var rgb2 = color2.match(p);
var rgb3 = color3.match(p);
document.write(rgb1 + "</br>");
document.write(rgb2 + "</br>");
document.write(rgb3);

UPDATE2 要正确匹配rgb或rgba颜色,您需要使用更长的模式。希望有人能提出比以下版本更好的版本:

/(\s?(?:rgb\((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]),\s*){2}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\)|rgba\((?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]),\s*){3}(?:0(\.[0-9])?|1|1.0)\))\s?)/gi

REGEX EXPLANATION

(               #capturing group starts
\s?             #match 0 or 1 space
(?:             #1st non-capturing group starts
rgb\(           #match rgb( literally
(?:             #2nd non-capturing group starts     
(?:             #3nd non-capturing group starts
25[0-5]|        #match 250 to 255, OR
2[0-4][0-9]|    #match 200 to 249, OR
1[0-9][0-9]|    #match 100 to 199, OR
[1-9][0-9]|     #match 10 to 99, OR
[0-9]           #match 0 to 9
)               #3rd non-capturing group ends
,               #match comma (,) literally
\s*             # match 0 or more spaces
)               #2nd non-capturing group ends
{2}             #repeat pattern 2 times for rgb
(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])
                #same pattern as above but no comma(,) or spaces             
\)              #match ) literally
|               #OR
rgba\(          #match rgba( literally
(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]),\s*)
                #same pattern as 2nd non-capturing group
{3}             #repeat pattern 3 times for rgba
(?:             #6th non-capturing group starts
0(\.[0-9])?|    #match 0.0 to 0.9 for the last value, OR
1|1.0           #match 1 or 1.0 for the last value  
)               #6th non-capturing group ends           
\)              #match ) literally
)               #1st non-capturing group ends
\s?             #match 0 or 1 space
)               #capturing group ends

REGEX 101 Demo

答案 1 :(得分:1)

我尝试简化你的正则表达式,将它们全部放在一个模式中:

/#(?:[\da-f]{3}){1,2}\b|rgba?\([\d, ]+\)/ig
因为rgb / rgba / #似乎足够清楚,所以你不必检查空间或任何事情。在rgb()的情况下,也不应该检查后面的空间,因为它始终以括号结束。

  • #(?:[\da-f]{3}){1,2}\b将匹配#后跟三个十六进制字符一次或两次(总共3或6个)和一个单词boundarie(空格,字符串结尾,komma - 除字母,数字之外的任何内容或者下划线)
  • rgba?\([\d, ]+\)将匹配rgb或rgba,后跟一个左括号,其中包含多个数字或逗号或空格以及一个右括号

查看https://regex101.com/r/aA3aW2/1一组样本。

如果您希望它们是单独的模式,您可以轻松地将它们再次分割为

/#(?:[\da-f]{3}){1,2}\b/ig
/rgba?\([\d, ]+\)/ig

如果您想保留空格,则需要将模式更改为

/\s?(?:#(?:[\da-f]{3}){1,2}\b|rgba?\([\d, ]+\))\s?/ig
/\s?#(?:[\da-f]{3}){1,2}\b\s?/ig
/\s?rgba?\([\d, ]+\)\s?/ig

编辑: 由于你还想验证一个正确的格式,正则表达式需要更长时间,为了解决这个问题,这就是我现在所拥有的:

/\s?(?:#(?:[\da-f]{3}){1,2}\b|rgb\((?:(?:[01]?\d?\d|2[0-4]\d|25[0-5]),\s*){2}(?:[01]?\d?\d|2[0-4]\d|25[0-5])\s*\)|rgba\((?:(?:[01]?\d?\d|2[0-4]\d|25[0-5]),\s*){3}(?:0(?:\.\d+)?|1(?:\.0+)?)\s*\))\s?/ig

有关更新的样本集,请参阅https://regex101.com/r/aA3aW2/2