我正在尝试编写从 CSS 代码中提取所有十六进制颜色的正则表达式。
这就是我现在拥有的:
代码:
$css = <<<CSS
/* Do not match me: #abcdefgh; I am longer than needed. */
.foo
{
color: #cccaaa; background-color:#ababab;
}
#bar
{
background-color:#123456
}
CSS;
preg_match_all('/#(?:[0-9a-fA-F]{6})/', $css, $matches);
输出:
Array
(
[0] => Array
(
[0] => #abcdef
[1] => #cccaaa
[2] => #ababab
[3] => #123456
)
)
我不知道如何指定只匹配那些以标点符号、空格或换行符结尾的颜色。
由于十六进制颜色代码也可能由 3 个字符组成,因此您可以定义一个强制组和一组可选的字母和数字,因此长而详细的表示法将是:
/#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/
或者,如果您想要一个漂亮而简短的版本,您可以说您想要 1 组或 2 组 3 个字母数字字符,并且它们应该不区分大小写地匹配 (
/i
)。
/#([a-f0-9]{3}){1,2}\b/i
如果正则表达式引擎支持此 posix 字符类,您也可以编写
[a-f0-9]
,而不是 [[:xdigit:]]
。在这种情况下,您可以跳过末尾的 /i
,整个公式仅多了两个字符,但可以说更具描述性。
/#([[:xdigit:]]{3}){1,2}\b/
接受的答案向您展示了如何使用正则表达式提取十六进制代码,因为这是提出的问题。
如果您想要验证隔离字符串是否是十六进制代码,则可以使用两个非正则表达式函数。
if (ctype_xdigit($color) && strlen($color)==6) {
// yay, it's a hex color!
}
GolezTrol 的答案的简短版本,避免两次写入字符集:
/#([a-fA-F0-9]{3}){1,2}\b/
尽管这个问题已经很久了,我还是想修改以下内容:
^#([[:xdigit:]]{3}){1,2}$
,其中 [[:xdigit:]]
是 [a-fA-F0-9]
的简写。
所以:
<?php preg_match_all("/^#(?>[[:xdigit:]]{3}){1,2}$/", $css, $matches) ?>
这里还值得注意的是非捕获组的使用
(?>...)
,以确保我们不会将数据存储在我们本来不想存储的内存中。
我不完全确定我是否正确,但如果你只想在 CSS 行末尾匹配十六进制颜色:
preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);
应该可以,我所做的就是添加可选的
\s;
字符组(可选的分号和空格)和换行符(不是可选的),它似乎可以工作。#FFF;
也有效。
对此进行测试时:
$css = '/* Do not match me: #abcdefgh; I am longer than needed. */
.foo
{
color: #CAB;
background-color:#ababab;
}';
preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);
var_dump($matches);
输出是:
array (array('#CAB;','#ababab;'))
如果您还想支持十六进制颜色的 Alpha 通道,例如
#FF0000AA
(9位数字),您可以使用:
// make sure it is a valid hexcolor value
if (preg_match("/(#[0-9A-Fa-f]{8})|(#[0-9A-Fa-f]{3,6})/", $color))
{
// valid hexcolor value
}
这对于 4 位数字(例如“#F00”)、7 位数字(例如“#FF0000”)和 9 位数字(例如“#FF0055AA”)的十六进制颜色有效。