Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS 颜色 正则 #11

Open
fisker opened this issue Jul 3, 2018 · 0 comments
Open

CSS 颜色 正则 #11

fisker opened this issue Jul 3, 2018 · 0 comments

Comments

@fisker
Copy link
Owner

fisker commented Jul 3, 2018

前几天想写个匹配颜色的正则,开始写的时候才发现,这个正则太长了

先了解下 css 中颜色的定义

参考 https://developer.mozilla.org/en-US/docs/Web/CSS/color_value

css 的颜色值

关键词

CSS 1

black, silver, gray, white, maroon, red, purple, fuchsia, green, lime, olive, yellow, navy, blue, teal, aqua

CSS 2.1

orange

CSS 3

aliceblue, antiquewhite, aquamarine, azure, beige, bisque, blanchedalmond, blueviolet, brown, burlywood, cadetblue, chartreuse, chocolate, coral, cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, darkgoldenrod, darkgray, darkgreen, darkgrey, darkkhaki, darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, darksalmon, darkseagreen, darkslateblue, darkslategray, darkslategrey, darkturquoise, darkviolet, deeppink, deepskyblue, dimgray, dimgrey, dodgerblue, firebrick, floralwhite, forestgreen, gainsboro, ghostwhite, gold, goldenrod, greenyellow, grey, honeydew, hotpink, indianred, indigo, ivory, khaki, lavender, lavenderblush, lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, lightgoldenrodyellow, lightgray, lightgreen, lightgrey, lightpink, lightsalmon, lightseagreen, lightskyblue, lightslategray, lightslategrey, lightsteelblue, lightyellow, limegreen, linen, magenta, mediumaquamarine, mediumblue, mediumorchid, mediumpurple, mediumseagreen, mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, navajowhite, oldlace, olivedrab, orangered, orchid, palegoldenrod, palegreen, paleturquoise, palevioletred, papayawhip, peachpuff, peru, pink, plum, powderblue, rosybrown, royalblue, saddlebrown, salmon, sandybrown, seagreen, seashell, sienna, skyblue, slateblue, slategray, slategrey, snow, springgreen, steelblue, tan, thistle, tomato, turquoise, violet, wheat, whitesmoke, yellowgreen

CSS 4

rebeccapurple

另外还有两个关键词

transparent 和 currentColor

RGB 颜色

十六进制的颜色值

#开头长度有 3, 4, 6, 8 共4种长度

rgb/rgba 函数

一般我们常用 rgb(255, 255, 255) 或者 rgba(0, 0, 0, 0)
但实际上 百分比也是可以的, 甚至还可以浮点数, 参数列表的逗号甚至也可以省略,

hls/hlsa 函数

一般我们常用 hsl(0, 100%, 50%) 或者 hsl(0, 100%, 50%, 1),这里函数也和rgb一样,非常多的格式


尝试写出这个正则,先整理下思路

// 关键词 很简单,直接列出来就行了

var keywords = 'black|silver|...'

// 16进制 这个也很简单 4种长度都列出来就行了
var hex = '#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})'

// rgb, 这里我只考虑常用的,其他的太复杂,也不常用,而且兼容性也没有很好
var rgb = 'rgb\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*\)'
// rgb开头一对括号里面3个允许有空格的整数
// 后面还有 rgba, hsl, hsla 都是类似的 所以我定义了一个函数来生成这个

function getFunctionalStringRe(func, args) {
  return func + '\\(' + args.map(function(arg) {
    return '\\s*' + arg + '\\s*'
  }).join(',') + '\\)'
}

var rgb = getFunctionalStringRe('rgb', ['\\d+', '\\d+', '\\d+'])
var rgba = getFunctionalStringRe('rgba', ['\\d+', '\\d+', '\\d+', '[.\\d]+'])
var hsl = getFunctionalStringRe('hsl', ['\\d+', '[.\\d]+%', '[.\\d]+%'])
var hsla = getFunctionalStringRe('hsla', ['\\d+', '[.\\d]+%', '[.\\d]+%', '[.\\d]+'])

// 最后把这些合并起来就行了 

var str = '^' +
 '(?:' + [keywords, hex, rgb, rgba, hsl, hsla].join('|') + ')'
 + '$'

var re = new RegExp(str, 'i')

完整代码

const colorRe = (function() {
  function getFunctionalStringRe(func, args) {
    return func + '\\(' + args.map(function(arg) {
      return '\\s*' + arg + '\\s*'
    }).join(',') + '\\)'
  }

  const keywords = 'black|silver|gray|white|maroon|red|purple|fuchsia|green|lime|olive|yellow|navy|blue|teal|aqua|orange|aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen|rebeccapurple|transparent|currentColor'
  const hex = '#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})'
  const rgb = getFunctionalStringRe('rgb', ['\\d+', '\\d+', '\\d+'])
  const rgba = getFunctionalStringRe('rgba', ['\\d+', '\\d+', '\\d+', '[.\\d]+'])
  const hsl = getFunctionalStringRe('hsl', ['\\d+', '[\\d]+%', '[.\\d]+%'])
  const hsla = getFunctionalStringRe('hsla', ['\\d+', '[.\\d]+%', '[.\\d]+%', '[.\\d]+'])

  return new RegExp('^' +
  '(?:' + [keywords, hex, rgb, rgba, hsl, hsla].join('|') + ')'
  + '$', 'i')
})()

console.log(colorRe)

除去关键词,仍然有200多个字符,算是比较复杂的一个正则了。

http://fiddle.jshell.net/fisker/bpqa4trc/14/show/light

如代码的注释所言,还有很多合法的颜色值没有被通过,可以再尝试改进

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant