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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12837942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:19:52  来源:igfitidea点击:

Regex for matching CSS hex colors

phpcssregexcolorshex

提问by Hemaulo

I'm trying to write regex that extracts all hex colors from CSS code.

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

This is what I have now:

这就是我现在所拥有的:

Code:

代码:

$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);

Output:

输出:

Array
(
    [0] => Array
        (
            [0] => #abcdef
            [1] => #cccaaa
            [2] => #ababab
            [3] => #123456
        )

)

I don't know how to specify that only those colors are matched which ends with punctuation, whitespace or newline.

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

回答by GolezTrol

Since a hex color code may also consist of 3 characters, you can define a mandatory group and an optional group of letters and digits, so the long and elaborate notation would be:

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

/#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/

Or if you want a nice and short version, you can say that you want either 1 or 2 groups of 3 alphanumeric characters, and that they should be matched case insensitively (/i).

或者,如果您想要一个漂亮而简短的版本,您可以说您想要 1 或 2 组 3 个字母数字字符,并且它们应该不区分大小写匹配 ( /i)。

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

Instead of [a-f0-9]you can also write [[:xdigit:]], if the regex engine supports this posix character class. In this case you can skip the /iat the end, and the whole formula is only two characters more, but arguably more descriptive.

相反的[a-f0-9],你也可以写[[:xdigit:]],如果正则表达式引擎支持这个POSIX字符类。在这种情况下,您可以跳过/i末尾的 ,整个公式仅多两个字符,但可以说更具描述性。

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

回答by robinst

Shorter version of GolezTrol's answerthat avoids writing the character set twice:

GolezTrol 的答案的较短版本,避免了两次写入字符集:

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

回答by modu

The accepted answer shows you how to do it with regex, because that was your question. But you really don't need to use regex for this. Normally this is how I would do it:

接受的答案向您展示了如何使用正则表达式进行操作,因为那是您的问题。但是你真的不需要为此使用正则表达式。通常我会这样做:

if(ctype_xdigit($color) && strlen($color)==6){
    // yay, it's a hex color!
}

for 100.000 iterations:

对于 100.000 次迭代:

Regex solution *: 0.0802619457245 seconds

正则表达式解决方案 *:0.0802619457245 秒

Xdigit with strlen: 0.0277080535889 seconds

Xdigit 与 strlen:0.0277080535889 秒

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

*:十六进制: ([a-fA-F0-9]{6})

回答by Berry M.

Despite this question's age I'd like to ammend the following:

尽管这个问题的年龄我想修改以下内容:

^#([[:xdigit:]]{3}){1,2}$, where [[:xdigit:]]is a shorthand for [a-fA-F0-9].

^#([[:xdigit:]]{3}){1,2}$,哪里[[:xdigit:]]是 的简写[a-fA-F0-9]

So:
<?php preg_match_all("/^#(?>[[:xdigit:]]{3}){1,2}$/", $css, $matches) ?>

所以:
<?php preg_match_all("/^#(?>[[:xdigit:]]{3}){1,2}$/", $css, $matches) ?>

Also noteworthy here is the usage of a non-capturing group (?>...), to ensure we don't store data in memory we never wanted to store in the first place.

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

Try it online

网上试试

回答by Elias Van Ootegem

I'm not entirely sure if I got this right, but if you only want to match hex colors at the end of a CSS line:

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

preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);

should work, all I did was add the optional \s;char group (optional semi-colon and spaces) and a line-break character (not optional) and it seemed to work.
And as @GolezTrol pointed out #FFF;is valid, too.

应该可以工作,我所做的只是添加了可选的\s;字符组(可选的分号和空格)和一个换行符(非可选),它似乎有效。
正如@GolezTrol 指出的那样,它#FFF;也是有效的。

When tested on this:

当对此进行测试时:

$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);

The output was:

输出是:

array (array('#CAB;','#ababab;'))