Разделитель Java-сканера обнаруживает ';'но не '\ n' - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть отформатированный текстовый файл, из которого мне нужно извлечь информацию и поместить в соответствующие переменные-члены в классе Item (1 строка текста = 1 Item).Я использую сканер и разделитель, но он может распознавать только разделяющую информацию ;, а не новые строки.

Я пробовал несколько различных выражений регулярных выражений, и мое последнее из них ниже, где я указываю толькоразделитель, который я знаю, подходит.Я также попробовал регулярное выражение [;\\n].Мой единственный вывод заключается в том, что сканер обрабатывает символы новой строки, отличные от других (что имеет смысл, я знаю, что у него есть функции, основанные на новых строках).

Вот формат текстового файла

1000;Knock Bits;88;12.67;8015
1001;Widgets;10;35.50;8004
1002;Grommets;20;23.45;8001

и вот как выглядит мой код

while (scan.hasNext())
{           
Item item = new Item();
scan.useDelimiter("[;]");

item.setID(scan.nextInt());
item.setName(scan.next());
item.setQuantity(scan.nextInt());
item.setPriceInCents((int) scan.nextFloat()*100);

scan.useDelimiter("\\n");
item.setSupplierID(scan.nextInt()); 
}

Весь приведенный выше код работает, кроме последней строки, получающей supplierID с nextInt().Я знаю, что могу просто заменить эту строку на

item.setSupplierID(Integer.parseInt(scan.nextLine()));

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

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

прочитать всю строку, затем использовать string.split (";"), чтобы получить элементы

List<Map<String,Object>> items = new ArrayList<>();
    try {
        Scanner scanner = new Scanner(new File(ClassLoader.getSystemResource("stats.txt").getFile()));
        while (scanner.hasNext()){
            String[] itemString = scanner.nextLine().split(";");
            Map<String,Object> item = new HashMap<>();
            item.put("id",Integer.parseInt(itemString[0]));
            item.put("name",itemString[1]);
            item.put("quant",Integer.parseInt(itemString[2]));
            item.put("price",Float.parseFloat(itemString[3]));
            item.put("suplierId",Integer.parseInt(itemString[4]));
            items.add(item);

        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    items.forEach(i->{
        i.forEach((key, value) -> System.out.println(key + " : " + value));
        System.out.println();
    });

Вместо Map вы можете просто заполнить анализируемые значения объекта

0 голосов
/ 07 февраля 2019

Используйте scanner.useDelimiter ("[; \ n]"); или scanner.useDelimiter ("[; \ r \ n]"); для работы в обеих Windowsи системы Linux.

Вызовите его вне цикла while:

    scanner.useDelimiter("[;\r\n]");

    while (scanner.hasNext()) {
        Item item = new Item();
        item.setID(scanner.nextInt());
        item.setName(scanner.next());
        item.setQuantity(scanner.nextInt());
        item.setPriceInCents((int) scanner.nextFloat()*100);
        item.setSupplierID(scanner.nextInt());
    }

Если используется \ R в соответствии с предложением mypetlion: scanner.useDelimiter ("; | \\ R");

...