Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 用于匹配CSS十六进制颜色的正则表达式_Php_Css_Regex_Colors_Hex - Fatal编程技术网

Php 用于匹配CSS十六进制颜色的正则表达式

Php 用于匹配CSS十六进制颜色的正则表达式,php,css,regex,colors,hex,Php,Css,Regex,Colors,Hex,我正在尝试编写从CSS代码中提取所有十六进制颜色的正则表达式 这就是我现在拥有的: 代码: 我不知道如何指定只匹配以标点、空格或换行符结尾的颜色。由于十六进制颜色代码也可能由3个字符组成,您可以定义一个强制组和一个可选的字母和数字组,因此长而复杂的符号是: /#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/ 或者,如果你想要一个简洁的版本,你可以说你想要1或2组3个字母数字字符,并且它们应该不区分大小写地匹配(/i) 如果正则表达式引擎支持

我正在尝试编写从CSS代码中提取所有十六进制颜色的正则表达式

这就是我现在拥有的:

代码:


我不知道如何指定只匹配以标点、空格或换行符结尾的颜色。

由于十六进制颜色代码也可能由3个字符组成,您可以定义一个强制组和一个可选的字母和数字组,因此长而复杂的符号是:

/#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/
或者,如果你想要一个简洁的版本,你可以说你想要1或2组3个字母数字字符,并且它们应该不区分大小写地匹配(
/i

如果正则表达式引擎支持此posix字符类,则也可以编写
[[:xdigit:][]
,而不是
[a-f0-9]
。在这种情况下,您可以跳过结尾的
/i
,整个公式只多了两个字符,但可以说更具描述性

/#([[:xdigit:]]{3}){1,2}\b/

我不完全确定我是否正确,但如果您只想在CSS行的末尾匹配十六进制颜色:

preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);
如果可以,我所做的只是添加可选的
\s
char组(可选分号和空格)和一个换行字符(非可选),它似乎可以工作。
正如@GolezTrol所指出的
#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;'))
的较短版本,可避免将字符集写入两次:

/#([a-fA-F0-9]{3}){1,2}\b/

公认的答案向您展示了如何使用正则表达式,因为这是您的问题。但是你真的不需要使用正则表达式。通常我会这样做:

if(ctype_xdigit($color) && strlen($color)==6){
    // yay, it's a hex color!
}
对于100.000次迭代:

正则表达式解*:0.0802619457245秒

带strlen的Xdigit:0.027708053889秒


*:hex:
([a-fA-F0-9]{6})

尽管这个问题已经很老了,但我想强调以下几点:

^#([:xdigit:]{3}{1,2}$
,其中
[:xdigit:]
[a-fA-F0-9]
的缩写

所以:

这里还值得注意的是,使用了非捕获组
(?>…)
,以确保我们不会将数据存储在一开始就不想存储的内存中


谢谢,\b这是我们需要的。不知道为什么会有“?”但是。无论如何,这是可以根据需要工作的:/#(?:[0-9a-fA-F]{6})\b/忘了提到3个字符代码是不需要的。问号要求前面的零或一次出现,使得第二个捕获的组是可选的。这些替换是没有意义的。这里有一个更简单的版本:
/#([a-fA-F0-9]){3}([a-fA-F0-9]){3})?\b/
@HamZa谢谢,没问题。事实上,我的正则表达式技能并没有提高多少,因为我很少使用它们。原因之一是可读性差。我对我写的这本书很满意,因为它可读性很强,即使有点多余。就像“普通”代码一样,我认为越短越好。我会留下你的版本,如果它是我答案的一个补充而不是完全替换的话。@evolross它匹配字符串中的颜色代码。它将匹配
#FFF#FF
中的
#FFF
,但不匹配最后一部分。如果要匹配精确的字符串,可以将字符串边界“锚定”添加到正则表达式中,使其类似于
^#([a-f0-9]{3}){1,2}\b$
。参见
https://regex101.com/r/LZJr63/1
用于细分。您可以使用
i
不区分大小写的匹配标志使其更简短
/#([a-f0-9]{3}{1,2}\b/i
谁将调用此函数100000次?抱歉,但这类事情太疯狂了。该函数在任何给定的PHP文件中最多调用5次?所以我们说的是几分之一毫秒?这个答案值得更多的投票。代码不仅快了3倍多,而且更短,更容易理解。但我想与#你能帮我吗?具体来说,这个答案值得更多的投票。函数在将来比正则表达式更容易理解和支持。不用担心正则表达式。见@modu的答案<代码>如果(ctype\uxDigit($color)和&strlen($color)==6)
array (array('#CAB;','#ababab;'))
/#([a-fA-F0-9]{3}){1,2}\b/
if(ctype_xdigit($color) && strlen($color)==6){
    // yay, it's a hex color!
}