Как получить доступ к каждому элементу после разделения - PullRequest
0 голосов
/ 07 февраля 2019

Я пытаюсь прочитать текстовый файл и разделить его на три отдельные категории.ID, адрес и вес.Однако всякий раз, когда я пытаюсь получить доступ к адресу и весу, у меня возникает ошибка.Кто-нибудь видит проблему?

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;

class Project1
{
public static void main(String[] args)throws Exception
{
    List<String> list = new ArrayList<String>();
    List<String> packages = new ArrayList<String>();
    List<String> addresses = new ArrayList<String>();
    List<String> weights = new ArrayList<String>();

    //Provide the file path
    File file = new File(args[0]);

    //Reads the file
    BufferedReader br = new BufferedReader(new FileReader(file));

    String str;
    while((str = br.readLine()) != null)
    {
        if(str.trim().length() > 0)
        {
            //System.out.println(str);
            //Splits the string by commas and trims whitespace
            String[] result = str.trim().split("\\s*,\\s*", 3);
            packages.add(result[0]);

            //ERROR: Doesn't know what result[1] or result[2] is.
            //addresses.add(result[1]);
            //weights.add(result[2]);

            System.out.println(result[0]);
            //System.out.println(result[1]);
            //System.out.println(result[2]);

        }   
    }

    for(int i = 0; i < packages.size(); i++)
    {
        System.out.println(packages.get(i));
    }

}
}

Вот текстовый файл (формат намеренный):

, 123-ABC-4567, 15 Вт. 15-я ул., 50,1

456-BgT-79876, 22 Broadway, 24

QAZ-456-QWER, 100 East 20th Street, 50

Q2Z-457-QWER, 200 East 20th Street, 49

678-FGH-9845, 45-й авеню, 12,2,

678-FGH-9846,45, 5-й авеню, 12,2

123-A BC-9999,46 Foo Bar, 220.0

347-poy-3465, 101 B'way, 24

, 123-FBC-4567, 15 West 15th St., 50.1

678-FGH-8465 45 5th Ave 12.2

Ответы [ 3 ]

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

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

([\w- ]+?)[ ,]+([\w .']+)[ ,]+([\d.]+)

Вот объяснение вышеприведенного регулярного выражения,

  • ([\w- ]+?) - Captures IDданные, которые состоят из символов слова, дефиса и пробела и помещают их в группу 1
  • [ ,]+ - это действует как разделитель, где он может быть одним или несколькими пробелами или запятыми
  • ([\w .']+) - этозахватывает address данные, которые состоят из символов слова, пробела и . и помещает их в группу2
  • [ ,]+ - снова разделитель, как описано выше
  • ([\d.]+) - это захватываетweight данные, которые состоят из чисел и . и помещают их в группу3

Демо

Вот модифицированная Javaкод, который вы можете использовать.Я удалил некоторые из ваших объявлений переменных, которые вы можете вернуть по мере необходимости.Этот код печатает всю информацию после захвата, как вы хотели, используя Matcher объект.

Pattern p = Pattern.compile("([\\w- ]+?)[ ,]+([\\w .']+)[ ,]+([\\d.]+)");

// Reads the file
try (BufferedReader br = new BufferedReader(new FileReader("data1.txt"))) {

    String str;
    while ((str = br.readLine()) != null) {
        Matcher m = p.matcher(str);
        if (m.matches()) {
            System.out.println(String.format("Id: %s, Address: %s, Weight: %s",
                    new Object[] { m.group(1), m.group(2), m.group(3) }));
        }
    }
}

Prints,

Id: 456-BgT-79876, Address: 22 Broadway, Weight: 24
Id: QAZ-456-QWER, Address: 100 East 20th Street, Weight: 50
Id: Q2Z-457-QWER, Address: 200 East 20th Street, Weight: 49
Id: 678-FGH-9845, Address: 45 5th Ave, Weight: 12.2
Id: 678-FGH-9846, Address: 45 5th Ave, Weight: 12.2
Id: 123-A BC-9999, Address: 46 Foo Bar, Weight: 220.0
Id: 347-poy-3465, Address: 101 B'way, Weight: 24
Id: 678-FGH-8465, Address: 45 5th Ave, Weight: 12.2

Дайте мне знать, если это работает для вас, и если у вас естьлюбой запрос дальше.

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

Вы можете добавить следующий код в свой код

            if (result.length > 0) {
                packages.add(result[0]);
            }
            if (result.length > 1) {
                addresses.add(result[1]);
            }
            if (result.length > 2) {
                weights.add(result[2]);
            }
0 голосов
/ 07 февраля 2019

Последняя строка содержит только один токен.Поэтому split будет возвращать массив только с одним элементом.

Пример минимального воспроизведения:

import java.io.*;

class Project1 {
    public static void main(String[] args) throws Exception {

        //Provide the file path
        File file = new File(args[0]);

        //Reads the file
        BufferedReader br = new BufferedReader(new FileReader(file));

        String str;
        while ((str = br.readLine()) != null) {
            if (str.trim().length() > 0) {
                String[] result = str.trim().split("\\s*,\\s*", 3);
                System.out.println(result[1]);
            }
        }
    }
}

С этим входным файлом:

678-FGH-8465 45 5th Ave 12.2

Вывод выглядит следующим образом:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at Project1.main(a.java:22)

Process finished with exit code 1

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

...