度过一个晚上的有趣方式!
代码
这里是:
/^rgba?\(\s*(?!\d+(?:\.|\s*\-?)\d+\.\d+)\-?(?:\d*\.\d+|\d+)(%?)(?:(?:\s*,\s*\-?(?:\d+|\d*\.\d+)\1){2}(?:\s*,\s*\-?(?:\d+|\d*\.\d+)%?)?|(?:(?:\s*\-?\d*\.\d+|\s*\-\d+|\s+\d+){2}|(?:\s*\-?(?:\d+|\d*\.\d+)%){2})(?:\s*\/\s*\-?(?:\d+|\d*\.\d+)%?)?)\s*\)$/i
此正则表达式对 rgba/RGBA 不区分大小写,因此我们可能应该i
在运行时保留该标志。
192 个字符!
为避免负前瞻并仅粗略匹配更常见的输入,请尝试
/^rgba?\(\d+(?:(?:\s*,\s*\d+){2}(?:\s*,\s*(?:\d*\.\d+|\d+)%?)?)|(?:(?:\s+\d+){2}(?:\s*\/\s*(?:\d*\.\d+|\d+)%?)?)\)$/
请注意,这目前仅对测试有效性有用。添加可靠的捕获组会延长并使其复杂化,超过我可以轻松掌握的水平。我们可以在验证后提取数字:
regexStr
.match(/\((.+)\)/)[1]
.trim()
.split(/\s*[,\/]\s*|\s+/)
背景
这段代码的目的是特别匹配当前 CSS 允许的 rgb/rgba 值。可能不适合每个人的用例,但这就是 Bounty 的用途。
自发布以来,CSS 现在允许rgb(R G B / A)
. 它还允许所有值的百分比、负数和小数。因此,这些是有效的:
✔ rgb(1, -2, .3, -.2)
✔ rgb(1 -2 .3 / -.2)
✔ rgb(1 -2 .3 / -.2%)
✔ rgb(1% -2% .3% / -.2%)
✔ rgb(1% -2% .3% / -.2)
使用百分比时,所有三个颜色值也必须是百分比。alpha 可以是任何环境中的百分比。
在写这篇文章的时候,我还发现了一个使用正则表达式很难实现的地方。
✔ rgb(1 .2.3)
✔ rgb(1-.2.3)
✘ rgb(1.2.3)
✘ rgb(1 -2.3)
使用时,底部的 2 个示例是错误的CSS.supports(color, str)
。本质上,如果看起来可能只rgb()
包含 2 个值,它将注册为无效。
我们可以通过创建一个可变长度的负前瞻来直接处理这个特殊情况。如果我们想将此正则表达式转移到另一个引擎,这可能很重要。
(?!\d+(?:\.|\s*\-?)\d+\.\d+)
1.2.3
它只是在早期拒绝,1 2.3
和的匹配1 -2.3
。
代码演练
这是一个巨大的,所以我会一个一个地把它拆开。我将假装我们正在处理扩展模式,因此我将在正则表达式中添加空格和注释以使事情更清晰。
^rgba?\(\s*
(?!\d+(?:\.|\s*\-?)\d+\.\d+) # negative lookahead
\-?(?:\d*\.\d+|\d+) # handle 1,-1,-.1,-1.1
(%?) # save optional percentage
- 首先,我们将其
a
设为可选并允许括号后的空格。
- 我们为 2 种特殊情况添加了负面预测。
- 然后我们匹配我们的第一个数字。我们的数字可以是整数、小数,也可能是负数。
- 我们捕获可选百分比。这是为了稍后通过利用反向引用来节省字符。我们用这个节省了大约 60 个字符。
(?: # next 2-3 numbers either
(?: # 2 separated by commas
\s*,\s*
\-?(?:\d+|\d*\.\d+)
\1
){2}
(?: # optional third maybe-percentage
\s*,\s*
\-?(?:\d+|\d*\.\d+)
%?
)?
- 接下来,捕获逗号分隔值。
\1
指的是%
如果它更早存在
- 让我们的第三个数字有一个百分比,而不管前面的数字是否有一个。
|(?: # match space-separated numbers
(?: # non-percentages
\s*\-?\d*\.\d+ # space-optional decimal
|\s*\-\d+ # space-opt negative
|\s+\d+ # space-req integer
){2}
|(?: # or percentages
\s*
\-?(?:\d+|\d*\.\d+)
%
){2}
)
(?: # optional third maybe-percentage
\s*\/\s*
\-?(?:\d+|\d*\.\d+)
%?
)?
.
首先尝试匹配由,-
或空格分隔的非百分比数字。
- 如果不匹配,尝试百分比数字,空格可选
- 可选地匹配 alpha 值,由分隔
/