Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Парсилка списка чисел, регулярные выражения 
V
    Опции темы
compiler91
  Дата 8.11.2009, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 18.6.2008
Где: Харьков, Украина

Репутация: нет
Всего: нет



Добрый день!
Есть задача: из списка целых чисел представленного строкой в формате "1, 2, 34, 5" получить массив этих самых чисел. При неверных входных данных возвращать null.
Задачу решаю используя regexp.
Вот что у меня получилось:
(\d+)  - число
(?: (\d+) ,) - число с запятой
(?: (\d+) ,)+? - список чисел заканчивающихся запятой
^(?: (\\d+) ,)+? (\\d+)$ - итого
Листинг программы:
Код

import java.util.Scanner;
import java.util.regex.*;

public class Runner {
    public static void main(String[] args) {
        String n = " ^(?: (\\d+) ,)+? (\\d+)$";
        System.out.println(n);
        Pattern p = Pattern.compile(n, Pattern.COMMENTS);
        Scanner scanner = new Scanner(System.in);
        boolean done = false;
        while(!done){
            String s = scanner.nextLine();
            if(s.equals("quit")){
                done = true;
            } else {
                Matcher m = p.matcher(s.replaceAll(" ", ""));
                while(m.find()){
                    System.out.println("find");
                    for(int i = 0; i < m.groupCount(); i++){
                        System.out.println(i + " : " + m.group(i));
                    }
                }
            }
        }
    }
}

Но где-то вкралась ошибка. Помогите, пожалуйста, ее найти.
Заранее благодарен.

PM MAIL   Вверх
Galaran
Дата 8.11.2009, 13:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 91
Регистрация: 25.5.2009

Репутация: 1
Всего: 2



Код

String[] array = string.split(", ");


Регекспом указывается разделитель
PM MAIL   Вверх
compiler91
Дата 8.11.2009, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 18.6.2008
Где: Харьков, Украина

Репутация: нет
Всего: нет



Хм.. Спасибо, как-то не пришло в голову.
Но все же, наверно, уже больше ради спортивного интереса, как это описать одним регулярным выражением?

Galaran-у еще раз спасибо!)
PM MAIL   Вверх
duk
Дата 8.11.2009, 14:47 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Some Object
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 19.7.2007

Репутация: 4
Всего: 4



Вот, посмотрите. Можно сделать следующим образом:
Код

import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.*;

public class Runner {
    public static Object[] getNumbArrFromString(String str) {
        String n = "\\d+";
        Pattern p = Pattern.compile(n);
        Matcher m = p.matcher(str);
        ArrayList<Integer> list = new ArrayList<Integer>();
        while (m.find()) {
            int start = m.start();
            int end = m.end();
            String match = str.substring(start, end);
            list.add(Integer.parseInt((match)));
        }
        Object[] o = list.toArray();
        list.clear();
        return o;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        boolean done = false;
        while (!done) {
            String s = scanner.nextLine();
            if (s.equals("quit")) {
                done = true;
            } else {
                Object[] arr = getNumbArrFromString(s);
                for (int i = 0; i < arr.length; i++)
                    System.out.print(arr[i] + " ");
                System.out.println();
            }
        }
    }

}


В таком случае, разделителями может выступать абсолютно все, кроме чисел (и к тому же удовлетворяет Вашему заданию).

Это сообщение отредактировал(а) duk - 8.11.2009, 14:49
PM MAIL   Вверх
compiler91
Дата 8.11.2009, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 18.6.2008
Где: Харьков, Украина

Репутация: нет
Всего: нет



duk, спасибо за предложенное Вами решение, но, увы, оно не вполне удовлетворяет заданию. Дело в том, что данная парсилка (или парсер?) должна обязательно сигнализировать если существует хотя бы малейшее отклонение от требуемого формата и не в коем случае не пытаться что-либо исправить. Ваш метод легко модернизировать чтобы он удовлетворял условие, например, вырезая полученный substring, а в конце анализируя "остаток", но в таком ключе вариант со split() получается элегантней;)





Это сообщение отредактировал(а) compiler91 - 8.11.2009, 15:11
PM MAIL   Вверх
duk
Дата 8.11.2009, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Some Object
*


Профиль
Группа: Участник
Сообщений: 179
Регистрация: 19.7.2007

Репутация: 4
Всего: 4



compiler91, эт я ради Вашего спортивного интереса написал  smile 
PM MAIL   Вверх
compiler91
Дата 8.11.2009, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 18.6.2008
Где: Харьков, Украина

Репутация: нет
Всего: нет



Цитата(duk @ 8.11.2009,  14:24)
compiler91, эт я ради Вашего спортивного интереса написал  smile

 smile 

Чую я это решается с помощью жадных квантификаторов(во!), а применить не могу(
PM MAIL   Вверх
goodday1941
Дата 9.11.2009, 14:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 709
Регистрация: 16.7.2006
Где: Украина, Киев

Репутация: 1
Всего: 9



Scanner не пробывали использовать для таких целей?

очень клевая штука как по мне ) в свое время лешила кучи головной боли при парсе файлов больших размеров


--------------------
SCJP 6
PM MAIL ICQ Skype GTalk   Вверх
compiler91
Дата 9.11.2009, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 18.6.2008
Где: Харьков, Украина

Репутация: нет
Всего: нет



goodday1941, спасибо. Не пробовал.
В данном решении есть интересная особенность - возможна привязка к локали*.

*-это помимо возможности чтения из потоков и т.д.)
PM MAIL   Вверх
lazycat
Дата 10.11.2009, 08:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 15.7.2007

Репутация: 1
Всего: 1



Вы твердо решили использовать именно механизм регулярных выражений?
Дело в том, что их возможности принципиально ограничены. Например, давайте в качестве примера перепишем задачу следующим образом:
Массив может содержать не только целые числа, но и числа в формате с фиксированной точкой, а разделителем может выступать не только запятая, но и точка с запятой и даже точка, при этом если разделителем является точка, то после нее обязательно должен следовать пробел. Например, строка может иметь такой вид:

1,56, 336.23;48.22. 11

Правила разбора сформулировать можно, но они слишком сложны для регулярных выражений.
Поэтому советую изучить инструмент JavaCC. Придется потратить некоторое время, но зато после этого проблема синтаксического разбор возникать не будет.

PM MAIL   Вверх
compiler91
Дата 10.11.2009, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 18.6.2008
Где: Харьков, Украина

Репутация: нет
Всего: нет



Цитата
Вы твердо решили использовать именно механизм регулярных выражений?
Решения задачи я оформил на базе splita-a, но, для личностного развития, хотел бы увидеть решение с использованием regexp. 

Цитата
Поэтому советую изучить инструмент JavaCC. Придется потратить некоторое время, но зато после этого проблема синтаксического разбор возникать не будет.
Действительно интересный инструмент. Огромное спасибо за то, что "ткнули носом" - в ближайшее время обязательно рассмотрю.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0488 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.