【问题标题】:Parsing a "rgb (x, x, x)" String Into a Color Object将“rgb (x, x, x)”字符串解析为颜色对象
【发布时间】:2011-09-30 17:38:56
【问题描述】:

是否有将字符串“rgb (x, x, x)” [在这种情况下 x 为 0-255] 解析为颜色对象的有效方法/现有解决方案? [我打算使用颜色值将它们转换为十六进制颜色等值。

我希望有一个 GWT 选项。我也意识到使用像 Scanner.nextInt 这样的东西会很容易。不过,我一直在寻找一种更可靠的方式来获取这些信息。

【问题讨论】:

    标签: java gwt colors


    【解决方案1】:

    据我所知,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)"));  
    

    【讨论】:

    • 这是我正在考虑的,但我想在实际尝试正则表达式之前进行验证
    • @monksy 你说的验证是什么意思?
    • 对不起,我的意思是验证没有现有的解决方案......即在进入 RegEx 解决方案之前可用 RGBColorInterpreter。遗憾的是,GWT 对正则表达式的支持不是很好。但我喜欢这个解决方案。
    【解决方案2】:

    对于不懂正则表达式的用户:

    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;
    

    关键是您不需要乍一看没人理解的复杂正则表达式。添加错误条件是一项简单的任务。

    【讨论】:

    • 这不是一个很好的解决方案,因为它假定传入的字符串将始终采用您期望的格式。此外,它假设您总是会从中获得 3 的回报。 [这就是我想避免使用 Scanner 的原因]
    • camickr,我必须支持僧侣。正则表达式是适合这项工作的工具,像 stackoverflow 这样的论坛的目的是让经验不足的程序员和工程师研究更有经验的程序员和工程师提供的解决方案,并在此过程中变得更有经验。值得庆幸的是,投票机制将帮助人们找到“正确”的解决方案——也就是说,这个解决方案不仅可能为他们提供所需的行为,而且还可能为他们提供学习新事物的机会,在这种情况下,它是广泛有用的。我的两分钱。
    • Camic 性能明智,你是对的。然而,这种方法的灵活性和可读性会受到影响。我不会对此投反对票,因为它是一个有效的解决方案。
    • 正则表达式看起来很糟糕,因为它允许任意数量的空格,并且在 Java 中必须对所有内容进行双重转义,但它是 IMO 更清洁的解决方案。我已经编辑了它;现在它应该看起来更好了。
    • 大部分编程都花在维护代码上。因此代码应该易于理解和维护。除非您实际上对 Regex 有所了解,否则任何人都无法理解该代码。在此基础上,我的代码更具可读性。正则表达式不是万能的解决方案。看看论坛上寻求正则表达式帮助的帖子数量。大多数人不理解他们。即使是初学者也能理解“if 语句”。如果没有其他替代方案,那么请务必使用正则表达式,但我只是提供了一个简单的替代方案。
    【解决方案3】:

    我仍然更喜欢正则表达式解决方案(并因此投票),但 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 整数。

    【讨论】:

    • Agghh.... 讨厌,我讨厌在建议的代码中看到单元测试.. 否则看起来很酷
    • 大声笑,是的,我有点匆忙。在编译之间执行此操作。但今后,我会将它们分开。干杯。
    • 哦,没问题,当我第一次看到它时,我就像“那不是很干净,但后来我注意到“哦,第二个部分是测试”
    • 我喜欢这样的工具,但同样,我不会将它用于这么简单的事情。对我来说,这太过分了。这会给解决方案增加额外的复杂性,因为现在您需要使用 3rd 方类。
    【解决方案4】:

    还有 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      • 1970-01-01
      相关资源
      最近更新 更多