【发布时间】:2011-09-30 17:38:56
【问题描述】:
是否有将字符串“rgb (x, x, x)” [在这种情况下 x 为 0-255] 解析为颜色对象的有效方法/现有解决方案? [我打算使用颜色值将它们转换为十六进制颜色等值。
我希望有一个 GWT 选项。我也意识到使用像 Scanner.nextInt 这样的东西会很容易。不过,我一直在寻找一种更可靠的方式来获取这些信息。
【问题讨论】:
是否有将字符串“rgb (x, x, x)” [在这种情况下 x 为 0-255] 解析为颜色对象的有效方法/现有解决方案? [我打算使用颜色值将它们转换为十六进制颜色等值。
我希望有一个 GWT 选项。我也意识到使用像 Scanner.nextInt 这样的东西会很容易。不过,我一直在寻找一种更可靠的方式来获取这些信息。
【问题讨论】:
据我所知,Java 或 GWT 没有类似的内置功能。您必须编写自己的方法:
public static Color parse(String input)
{
Pattern c = Pattern.compile("rgb *\\( *([0-9]+), *([0-9]+), *([0-9]+) *\\)");
Matcher m = c.matcher(input);
if (m.matches())
{
return new Color(Integer.valueOf(m.group(1)), // r
Integer.valueOf(m.group(2)), // g
Integer.valueOf(m.group(3))); // b
}
return null;
}
你可以这样使用
// java.awt.Color[r=128,g=32,b=212]
System.out.println(parse("rgb(128,32,212)"));
// java.awt.Color[r=255,g=0,b=255]
System.out.println(parse("rgb (255, 0, 255)"));
// throws IllegalArgumentException:
// Color parameter outside of expected range: Red Blue
System.out.println(parse("rgb (256, 1, 300)"));
【讨论】:
对于不懂正则表达式的用户:
public class Test
{
public static void main(String args[]) throws Exception
{
String text = "rgb(255,0,0)";
String[] colors = text.substring(4, text.length() - 1 ).split(",");
Color color = new Color(
Integer.parseInt(colors[0].trim()),
Integer.parseInt(colors[1].trim()),
Integer.parseInt(colors[2].trim())
);
System.out.println( color );
}
}
编辑:我知道有人会评论错误检查。我把它留给了海报。这样做很容易处理:
if (text.startsWith("rgb(") && text.endsWith(")"))
// do the parsing
if (colors.length == 3)
// build and return the color
return null;
关键是您不需要乍一看没人理解的复杂正则表达式。添加错误条件是一项简单的任务。
【讨论】:
我仍然更喜欢正则表达式解决方案(并因此投票),但 camickr 确实指出正则表达式有点晦涩,尤其是对于今天没有使用过 Unix 的孩子(当时它是一个男人的操作系统,只有一个命令行界面——嘘!!)。所以这是我提供的高级解决方案,不是因为我认为它更好,而是因为它作为如何使用一些漂亮的 Guava 函数的示例:
package com.stevej;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
public class StackOverflowMain {
public static void main(String[] args) {
Splitter extractParams = Splitter.on("rgb").omitEmptyStrings().trimResults();
Splitter splitParams =
Splitter.on(CharMatcher.anyOf("(),").or(CharMatcher.WHITESPACE)).omitEmptyStrings()
.trimResults();
final String test1 = "rgb(11,44,88)";
System.out.println("test1");
for (String param : splitParams.split(Iterables.getOnlyElement(extractParams.split(test1)))) {
System.out.println("param: [" + param + "]");
}
final String test2 = "rgb ( 111, 444 , 888 )";
System.out.println("test2");
for (String param : splitParams.split(Iterables.getOnlyElement(extractParams.split(test2)))) {
System.out.println("param: [" + param + "]");
}
}
}
输出:
test1
参数:[11]
参数:[44]
参数:[88]
test2
参数:[111]
参数:[444]
参数:[888]
这是没有正则表达式的正则表达式。
作为练习留给读者添加检查(a)“rgb”出现在字符串的开头,(b)括号平衡并正确定位,以及(c)正确的数量返回格式化的 rgb 整数。
【讨论】:
还有 C# 形式:
public static bool ParseRgb(string input, out Color color)
{
var regex = new Regex("rgb *\\( *([0-9]+), *([0-9]+), *([0-9]+) *\\)");
var m = regex.Match(input);
if (m.Success)
{
color = Color.FromArgb(int.Parse(m.Groups[1].Value), int.Parse(m.Groups[2].Value), int.Parse(m.Groups[3].Value));
return true;
}
color = new Color();
return false;
}
【讨论】: