Как извлечь некоторые данные из текстового файла в Java SE 1.6?

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

Я работаю над графиками, которые хранятся в текстовом файле примерно так (пробелы можно игнорировать):

A: (B, 4.5), (C, 5.8)
B: (A, 3)
C:

С моей реализацией Graph, чтобы получить тот же график, я бы сделал что-то вроде этого:

StdGraph<String> graph = new StdGraph<String>();
graph.addSommet("A"); //1 -> add the vertex named "A" to the graph
graph.addSommet("B"); //2 -> add the vertex named "B" to the graph
graph.addSommet("C"); //3 -> add the vertex named "C" to the graph
graph.addArete("A", "B", 4.5); //4 -> add an edge between A and B with a weight of 4.5
graph.addArete("A", "C", 5.8); //5 -> add an edge between A and C with a weight of 5.8
graph.addArete("B", "A", 3.); //6 -> add an edge between B and A with a weight of 3.0

//note that 3 and 4 can switch places, and technically 6 could go right after 2

Это должно быть именно в таком порядке, потому что я не могу добавить ребро, если одна из вершин не существует. Моя реализация Graph работает, но я понятия не имею, как получить данные из моего текста; плюс я должен убедиться, что он соответствует правильному шаблону, потому что мне нужно проверить, что входной файл не является чем-то другим.

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

private String fileToString(File f) {
        StringBuilder str = new StringBuilder("");
        Scanner s = null;
        try {
            s = new Scanner(f);

        } catch (FileNotFoundException e) {
            System.out.println("ERREUR => FileNotFoundException");
            e.printStackTrace();
        }
        while (s.hasNext()) {
            str.append(s.nextLine());
        }
        String res = str.toString();
        res.replaceAll("//s", "");
        return res;
    }

и мое регулярное выражение для графиков таково (оно написано так, чтобы его было легче читать мне и моей группе Uni):

//Regex for a Vertex' name:
String SOMMETREGEX = "[a-zA-Z0-9\\-_/]*";
//Regex for an Edge's weight:
String POIDSREGEX = "[\\-+]?\\d+(\\.\\d+)?";
//Regex for one line composed of the vertex and its neighbors with the weight of the edges
String SOMANDSUIV = "("+SOMMETREGEX+":"
            + "(\\("+SOMMETREGEX+","+POIDSREGEX+"\\),)*"
            + "(\\("+SOMMETREGEX+","+POIDSREGEX+"\\))?\\n)";
//Regex for the full graph
String GRAPHREGEX = SOMANDSUIV + "*";

Наконец, у меня есть этот метод, который мне нужно выполнить, но я не знаю как:

private StdGraph<String> buildGraphFromFile(File f) {
        StdGraph<String> res = new StdGraph<String>();
        String stringOfFile = fileToString(f);
        if (!Pattern.matches(GRAPHREGEX, stringOfFile)) {
            return null;
        }
        
        // Stuff goes here but idk what
        
        return res;
    }

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

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

Мне нужно использовать Java 1.6, поэтому что-либо после этого просто не вариант

🤔 А знаете ли вы, что...
Java имеет систему управления зависимостями, известную как Maven.


57
1

Ответ:

Решено

Если вы не смогли найти подходящий парсер, вы можете использовать шаблон, подобный следующему:

"^\\s*([A-Z]{1,})\\s*:|\\s*(?:\\(\\s*([A-Z])\\s*,\\s*([^)\\r\\n]+)\\))"

чтобы найти свои узлы и веса.

Код

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegularExpression {
    public static void main(String[] args) {
        final String regex = "^\\s*([A-Z]{1,})\\s*:|\\s*(?:\\(\\s*([A-Z])\\s*,\\s*([^)\\r\\n]+)\\))";
        final String string = "A: (B, 4.5), (C, 5.8)\n"
                + "B: (A, 3)\n"
                + "C:\n"
                + "E: (B, 4.5), (E, 5.8), (F, 5.8)\n"
                + "F: (A, 3)\n"
                + "G: (A, 3) , (E, 3) , (F, 3), (G, 3)";

        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));

            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }
    }
}


Принты

Full match: A:
Group 1: A
Group 2: null
Group 3: null
Full match:  (B, 4.5)
Group 1: null
Group 2: B
Group 3: 4.5
Full match:  (C, 5.8)
Group 1: null
Group 2: C
Group 3: 5.8
Full match: B:
Group 1: B
Group 2: null
Group 3: null
Full match:  (A, 3)
Group 1: null
Group 2: A
Group 3: 3
Full match: C:
Group 1: C
Group 2: null
Group 3: null
Full match: E:
Group 1: E
Group 2: null
Group 3: null
Full match:  (B, 4.5)
Group 1: null
Group 2: B
Group 3: 4.5
Full match:  (E, 5.8)
Group 1: null
Group 2: E
Group 3: 5.8
Full match:  (F, 5.8)
Group 1: null
Group 2: F
Group 3: 5.8
Full match: F:
Group 1: F
Group 2: null
Group 3: null
Full match:  (A, 3)
Group 1: null
Group 2: A
Group 3: 3
Full match: G:
Group 1: G
Group 2: null
Group 3: null
Full match:  (A, 3)
Group 1: null
Group 2: A
Group 3: 3
Full match:  (E, 3)
Group 1: null
Group 2: E
Group 3: 3
Full match:  (F, 3)
Group 1: null
Group 2: F
Group 3: 3
Full match:  (G, 3)
Group 1: null
Group 2: G
Group 3: 3

Примечание

  • Остальное вы можете закодировать.
  • Первая группа — это узел, а остальные группы — соседние узлы.