在 php 中使用正则表达式验证 hex 和 rgba 颜色

Posted

技术标签:

【中文标题】在 php 中使用正则表达式验证 hex 和 rgba 颜色【英文标题】:Validation hex and rgba colors using regex in php 【发布时间】:2017-09-28 02:23:46 【问题描述】:

我正在使用 Laravel,并且正在尝试验证颜色字段。 此文本框应仅允许使用正则表达式模式的 HEXrgbrgbahslhsla 颜色。

在我的控制器中,我有这种模式,但它没有验证我的字段值。任何字符串都会通过验证。

$this->validate($request, [
    'color' => [
        'required',
        'regex:/(#(?:[0-9a-f]2)2,4|#[0-9a-f]3|(?:rgba?|hsla?)\((?:\d+%?(?:deg|rad|grad|turn)?(?:,|\s)+)2,3[\s\/]*[\d\.]+%?\))/i', // <--- not working
    ],
]);

谢谢。

【问题讨论】:

出于测试目的,请提供实际输入的简短列表,以便测试我的模式。 您只需要使用^$ 锚点...但是请注意您的正则表达式:它似乎匹配rgb(2,2,2,2)rgba(3,3,3,33)(第一个不应该匹配,因为它是 rgb,而不是 rgba,并且第二个不应该匹配任何高于 1 的不透明度) @AbdallaArbab 请查看我的帖子我已更新,请查看演示链接 【参考方案1】:

您应该添加锚点(^$):

'regex:/^(#(?:[0-9a-f]2)2,4|#[0-9a-f]3|(?:rgba?|hsla?)\((?:\d+%?(?:deg|rad|grad|turn)?(?:,|\s)+)2,3[\s\/]*[\d\.]+%?\))$/i',
        ^                                                                                                                     ^

使正则表达式应用于整个输入,而不是仅仅匹配它。

但请注意,您的模式允许输入像 rgba(1024, 1023, 0) 这样的无效颜色。


如果您想要更防弹的正则表达式,请使用此 (demo):

^(\#[\da-f]3|\#[\da-f]6|rgba\(((\d1,2|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*)2((\d1,2|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|hsla\(\s*((\d1,2|[1-2]\d2|3([0-5]\d|60)))\s*,\s*((\d1,2|100)\s*%)\s*,\s*((\d1,2|100)\s*%)(,\s*(0\.\d+|1))\)|rgb\(((\d1,2|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*)2((\d1,2|1\d\d|2([0-4]\d|5[0-5]))\s*)|hsl\(\s*((\d1,2|[1-2]\d2|3([0-5]\d|60)))\s*,\s*((\d1,2|100)\s*%)\s*,\s*((\d1,2|100)\s*%)\))$

【讨论】:

点赞。我喜欢防弹正则表达式模式。对我来说看起来很可靠:sandbox.onlinephpfunctions.com/code/… @ThomasAyoub MateusA. 对这个问题的评论怎么样?我对预期的语法知之甚少。这是否已融入您的防弹模式?我想不是。你能让它更防弹吗? @mickmackusa 第一个只是检查模式,而不检查 rgba/hsla 表示的规则。第二个。 第二个模式 looks 就像它只允许零或 1 a 但随后不有条件地检查尾括号内的参数。正确的?我认为这是MatheusA. 的观点。进行这种调整可能会被认为是矫枉过正,并且肯定会使模式膨胀,但可以让您真正称其为防弹。 @mickmackusa 你是对的,我在那里有点懒惰:p【参考方案2】:

希望这对您有所帮助。在下面的正则表达式中,我也在处理空格,

1. #[a-zA-Z0-9]6 用于匹配字符串,如#090f00

2. rgb\((?:\s*\d+\s*,)2\s*[\d]+\) 这将匹配像 rgb(10, 10, 20) 这样的字符串

3. rgba\((\s*\d+\s*,)3[\d\.]+\) 这将匹配像 rgba(100,100,100,0.9) 这样的字符串

4. hsl\(\s*\d+\s*(\s*\,\s*\d+\%)2\) 这将匹配像 hsl(10,30%,40%) 这样的字符串

5. hsla\(\s*\d+(\s*,\s*\d+\s*\%)2\s*\,\s*[\d\.]+\) 这将匹配像 hsla(120, 60%, 70%, 0.3) 这样的字符串

正则表达式:

#[a-zA-Z0-9]6|rgb\((?:\s*\d+\s*,)2\s*[\d]+\)|rgba\((\s*\d+\s*,)3[\d\.]+\)|hsl\(\s*\d+\s*(\s*\,\s*\d+\%)2\)|hsla\(\s*\d+(\s*,\s*\d+\s*\%)2\s*\,\s*[\d\.]+\)

Regex demo

【讨论】:

@mickmackusa 稍等片刻 OP 使用不区分大小写的标志来省略 A-Z#fff 是有效的。所以6 太死板了 零或无穷大\s?我推荐 ` ?`(空格问号)\s 也允许其他空格字符。 @mickmackusa 有两个空格的情况。有没有可能?你能分享一个十六进制代码长度小于或大于6 % 不需要转义。

以上是关于在 php 中使用正则表达式验证 hex 和 rgba 颜色的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式怎么来验证输入框中只能输入整数而且不能以0开头;就是不能输入001这样的数字;

MyEclipse去除网上复制下来的代码带有的行号(使用正则表达式)

使用正则表达式从文本文件中解析 [重复]

MyEclipse使用总结——MyEclipse去除网上复制下来的来代码带有的行号

仅使用正则表达式在字符串中查找中间字符

MyEclipse:用正则表达式替换