Подтвердить что ты не робот

Разбор строки "rgb (x, x, x)" в цветовой объект

Существует ли эффективное/существующее решение для синтаксического анализа строки "rgb (x, x, x)" [где x в этом случае равно 0-255] в цветной объект? [Я планирую использовать значения цвета, чтобы преобразовать их в шестигранную цветовую эквивалентность.

Я бы предпочел, чтобы для этого был вариант GWT. Я также понимаю, что было бы легко использовать что-то вроде Scanner.nextInt. Однако я искал более надежный способ получить эту информацию.

4b9b3361

Ответ 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)"));  

Ответ 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

Я по-прежнему предпочитаю решение регулярного выражения (и проголосовал соответственно), но camickr делает вывод, что регулярное выражение немного неясное, особенно для детей, которые сегодня не использовали Unix (когда это была мужская операционная система с только интерфейс командной строки - Booyah!!). Итак, вот решение высокого уровня, которое я предлагаю, а не потому, что я думаю, что это лучше, но потому, что он служит примером того, как использовать некоторые изящные функции 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
param: [11] Параметр: [44] Параметр: [88]
test2
param: [111] Параметр: [444]
param: [888]

Это регулярное выражение без регулярного выражения.

В качестве упражнения для читателя добавляются проверки: (a) "rgb" появляется в начале строки, (b) скобки сбалансированы и правильно расположены, и (c) правильное количество правильно отформатированные числа rgb.

Ответ 4

И форма С#:

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