2013-05-16 3 views
-3

Я пытаюсь использовать Pattern для ввода цифр из строки.Не могу взять цифры из строки

Строка, которая содержит мои цифры выглядит следующим образом:

{1,3}{4,5}...{6,7} 

Мой вывод должен быть:

1 3 
4 5 
... 
6 7 

Код:

private static void products(final String products) { 
    final String regex = "(\\{([0-9]+),([0-9]+)\\})+"; 


    final java.util.regex.Pattern p = java.util.regex.Pattern.compile(regex); 

    final Matcher matcher = p.matcher(products); 
    if(!matcher.matches()) { 
     throw new IllegalArgumentException("Wrong semantic of products!"); 
    } 

    while(matcher.find()) { 
     System.out.print(matcher.group(1) + " "); 
     System.out.println(matcher.group(2)); 
    } 
} 

Проблема у меня в том, что вызов функции выше не выводит ничего. Как я могу это исправить?

+1

В чем проблема? – Andremoniy

+0

Это регулярное выражение "(\\ {([0-9] +), ([0-9] +) \\}) +" не работает для нахождения цифр в строке. – MAGx2

+0

@Andremoniy Это не работает ... – vikingsteve

ответ

2

Другое решение:

private static void products2(final String products) { 
    final String regex = "\\{([0-9]+),([0-9]+)\\}"; 

    if (products.split(regex).length > 0) { 
     throw new IllegalArgumentException("Wrong semantic of products!"); 
    } 

    final Matcher matcher = Pattern.compile(regex).matcher(products); 
    while (matcher.find()) { 
     System.out.print(matcher.group(1) + " "); 
     System.out.println(matcher.group(2)); 
    } 
} 

Это одно, вероятно, менее эффективен (String.split(...)) еще, возможно, более элегантной (отделяет валидация от обработки).

+0

Почему 'products.split (regex) .length> 0' ** would ** work - [' "Конечные пустые строки [поэтому] не включены в результирующий массив." '] (Http://docs.oracle. ком/JavaSE/7/документы/API/Java/языки/String.html # сплит (java.lang.String)). – Dukeling

+0

Не могли бы вы привести пример ввода, который тогда не сработает? – vikingsteve

+0

Это ** будет ** работать (по крайней мере, от того, что я могу сказать). Я только что опубликовал этот комментарий, если кто-то задается вопросом, почему ** он работает (потому что я это сделал). – Dukeling

3

В конце вы должны вынуть +, так как вы хотите извлечь их по одному.

Все это в скобках, это будет группа 1, либо сделать его несовпадающих группу (с ?:) или начать с 2. Удаление скобок не будет работать из-за добавления + в следующем регулярном выражении (см. код).

matcher.matches проверяет всю строку, которая не будет работать с регулярным выражением без +, для этого вам, вероятно, потребуется исходное регулярное выражение.

Кроме того, с помощью matches и затем find на том же Matcher не будет работать, так как matches будет перемещать текущую позицию в строке, таким образом, если они совпадают, то это будет в конце строки. Таким образом, find ничего не найдет, так как для поиска нет строки. Вы можете использовать reset на Matcher, чтобы сбросить его положение, но это, очевидно, не решит вышеуказанные проблемы.

Обновленный код:

private static void products(final String products) { 
    final String regex = "(?:\\{([0-9]+),([0-9]+)\\})"; 

    // validation 
    final Pattern pAll = Pattern.compile(regex + "+"); 

    if (!pAll.matcher(products).matches()) { 
     throw new IllegalArgumentException("Wrong semantic of products!"); 
    } 

    // extraction 
    final Pattern p = Pattern.compile(regex); 
    final Matcher matcher = p.matcher(products); 

    while (matcher.find()) { 
     System.out.print(matcher.group(1) + " "); 
     System.out.println(matcher.group(2)); 
    } 
} 

Test.

Для тех, кто заинтересован, вот способ сделать это в 1 проход: (matches проходит через всю строку, таким образом, в результате чего 2 проходит через строку)

private static void products(final String products) { 
    final String regex = "\\{([0-9]+),([0-9]+)\\}"; 

    final Pattern p = Pattern.compile(regex); 

    final Matcher matcher = p.matcher(products); 
    int lastEnd = 0; 
    while (matcher.find()) { 
     if (lastEnd != matcher.start()) 
      throw new IllegalArgumentException("Wrong semantic of products!"); 
     System.out.print(matcher.group(1) + " "); 
     System.out.println(matcher.group(2)); 
     lastEnd = matcher.end(); 
    } 
    if (lastEnd != products.length()) 
     throw new IllegalArgumentException("Wrong semantic of products!"); 
} 

Единственным недостатком является то, что он будет печатать выведите все значения до поиска неверных данных.

Например, products("{1,3}{4,5}a{6,7}"); напечатает:

1 3 
4 5 

перед бросать исключение (так как до, пока строка не действует).

+0

спасибо. – MAGx2

0

Другим решением было бы разбить строку на «}», а затем пройти через результирующий массив и извлечь числа. Каждый элемент массива должен соответствовать "\\ {(\\ D +), (\\ D +)"

Смежные вопросы