Java .split () выходит за пределы - PullRequest
0 голосов
/ 08 октября 2018

У меня проблема с моим кодом.

Я пытаюсь извлечь название канала из файла .txt.Я не могу понять, почему метод line.split() возвращает мне массив с длиной 0:

Кто-то может мне помочь?

Это файл .txt:

------------ [channel.txt] ---------------------

...
#CH id="" tvg-name="Example1" tvg-logo="http... 
#CH id="" tvg-name="Example2" tvg-logo="http...
#CH id="" tvg-name="Example3" tvg-logo="http...
#CH id="" tvg-name="Example4" tvg-logo="http...
...

Это мой код:

try {
    FileInputStream VOD = new FileInputStream("channels.txt");
    BufferedReader buffer_r = new BufferedReader(new InputStreamReader(VOD));
    String line;
    ArrayList<String> name_channels = new ArrayList<String>();

    while ((line = buffer_r.readLine()) != null ) {
        if (line.startsWith("#")) {
            String[] first_scan = line.split(" tvg-name=\" ", 2);
            String first = first_scan[1];               // <--- out of bounds

            String[] second_scan = first.split(" \"tvg-logo= ", 2);
            String second = second_scan[0];

            name_channels.add(second);

        } else {
            //...           
        }
    }
    for (int i = 0; i < name_channels.size(); i++) {
        System.out.println("Channel: " + name_channels.get(i));
    }
} catch(Exception e) {
    System.out.println(e);
}

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

После последней двойной кавычки в tvg-name=\" есть пробел, который не соответствует данным в вашем примере.

Если вы используете split с line.split(" tvg-name=\"", 2), тогда первый элемент в возвращенном массиве будет#CH id="" и вторая часть будет Example1" tvg-logo="http..."

Если вы хотите получить значение tvg-name=, вы можете использовать регулярное выражение с группой захвата, в которой вы бы не захватывали двойную кавычку с использованием отрицательного символакласс [^"]+

tvg-name="([^"]+)"

try {
    FileInputStream VOD = new FileInputStream("channels.txt");
    BufferedReader buffer_r = new BufferedReader(new InputStreamReader(VOD));
    String line;
    ArrayList<String> name_channels = new ArrayList<String>();

    while((line = buffer_r.readLine()) != null ){
        if(line.startsWith("#")){
            String regex = "tvg-name=\"([^\"]+)\"";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(line);

            while (matcher.find()) {
                name_channels.add(matcher.group(1));
            }
        } else {
            // ...
        }
    }
    for(int i = 0; i < name_channels.size(); i++){
        System.out.println("Channel: " + name_channels.get(i));
    }
}catch(Exception e){
    System.out.println(e);
}
0 голосов
/ 08 октября 2018

Итак, у вас есть примеры, подобные этому

#CH id="" tvg-name="Example1" tvg-logo="http... 

И вы пытаетесь разделить эти строки

" tvg-name=\" "
" \"tvg-logo= "

Ни одна из этих строк не приведена в примере.К нему добавлено паразитное пространство, а место в начале второго находится не в том месте.

Исправьте строки, и вот краткая, но полная программа для демонстрации

interface Split {
    static void main(String[] args) {
        String line = "#CH id=\"\" tvg-name=\"Example1\" tvg-logo=\"http...";

        String[] first_scan = line.split(" tvg-name=\"", 2);
        String first = first_scan[1];               // <--- out of bounds

        String[] second_scan = first.split("\" tvg-logo=", 2);
        String second = second_scan[0];

        System.err.println(second);
    } 
}

Конечно, если у вас есть строки, начинающиеся с '#', но не совпадающие, у вас возникнет аналогичная проблема.

Подобные вещи, вероятно, лучше подходят для регулярных выражений и групп захвата.

...