Разбор текстового файла в Java

1

У меня есть txt файл, который имеет ~ 900 вопросов, которые выглядят следующим образом:

На вопросы:

-----------------------------------------------------------------------------
  #0001 Which disease devastated livestock across the UK during 2001?
-----------------------------------------------------------------------------
 *Hand-and-foot
 *Foot-in-mouth
 *Hand-to-mouth
 *Foot-and-mouth

Answer: Foot-and-mouth

-----------------------------------------------------------------------------
  #0002 Which of these kills its victims by constriction?
-----------------------------------------------------------------------------
 *Andalucia
 *Anaconda
 *Andypandy
 *Annerobinson

Answer: Anaconda

У меня есть объект, который хранит вопрос, и объекты, которые хранят ответ

IE: Question.java

public class Question {
    private String questionText;
    private Answer a, b, c, d;

    public Question(String questionText, Answer a, Answer b, Answer c, Answer d) {
        this.questionText = questionText;
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }

    public String getQuestionText() {
        return questionText;
    }

    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }

    public Answer getA() {
        return a;
    }

    public void setA(Answer a) {
        this.a = a;
    }

    public Answer getB() {
        return b;
    }

    public void setB(Answer b) {
        this.b = b;
    }

    public Answer getC() {
        return c;
    }

    public void setC(Answer c) {
        this.c = c;
    }

    public Answer getD() {
        return d;
    }

    public void setD(Answer d) {
        this.d = d;
    }

    public String toString() {
        return  questionText +
                "\nA) " + a +
                "\nB) " + b +
                "\nC) " + c +
                "\nD) " + d;
    }
}

Answers.Java

public class Answer {
    private String answerText;
    private boolean correct;

    //constructor to set correct answer
    public Answer(String answerText, boolean correct) {
        this.answerText = answerText;
        this.correct = correct;
    }

    public Answer(String answerText) {
        this.answerText = answerText;
        this.correct = false;
    }

    public String getAnswerText() {
        return answerText;
    }

    public void setAnswerText(String answerText) {
        this.answerText = answerText;
    }

    public boolean isCorrect() {
        return correct;
    }

    public void setCorrect(boolean correct) {
        this.correct = correct;
    }

    public String toString() {
        return answerText;
    }
}

Я хотел бы создать список массивов, в котором хранятся все объекты вопроса, проанализированные из текстового файла. Я новичок в Java и ранее программировал на python, и немного запутался в том, как обрабатывать текстовые файлы в java, поскольку это кажется намного более сложным. Я знаю, как анализировать, например, по строкам или список слов, например. Я не знаю, как это сделать с дополнительным текстом в файле.

Любая помощь будет оценена по достоинству.

Пример двухлинейного вопроса:

-----------------------------------------------------------------------------
  #0016 Which word follows 'North' and 'South' to give the names of two
        continents?
-----------------------------------------------------------------------------
 *Africa
 *America
 *Asia
 *Australia

Answer: America
  • 0
    Я предлагаю вам иметь лучшую структуру вопросов, вы должны сделать ее привлекательной, а не в модели. Структурируйте текст как: number;question;answers;correctanswer
  • 2
    Представьте, что ваш файл содержит только один вопрос и ответы на него. Попробуйте разобрать его, а затем расширить свою логику, чтобы применить его к нескольким вопросам.
Теги:
text-parsing

3 ответа

1
Лучший ответ

Привет, вот что-то, что может сделать трюк;)

    String file = "text.txt";
    BufferedReader br = null;
    int nbAnswer = 4;
    try {
        br = new BufferedReader(new FileReader(file));
        String line;
        while((line = br.readLine()) != null) {   
            if( line.contains("-----------"))
            {
                line = br.readLine();
                String question = line.split("#[0-9]{4} ")[1];
                while(!(line = br.readLine()).contains("-----------"))
                    question += " " + line.trim();

                String[] answers = new String[4];

                for( int i = 0; i < nbAnswer; i++)
                    answers[i] = br.readLine().substring(2);

                br.readLine();
                String sol = br.readLine().split("Answer: ")[1];
                System.out.println(question + "\nanswer: " + answers[0] + " " + answers[1] + " " + answers[2] + " " + answers[3] + "\nsol " + sol);
            }
        }
    }
    catch(IOException ex) {
        System.err.println(ex);
    }

line.split("#[0-9]{4} ")[1]; является регулярным выражением, которое позволит вам разбить строку после #, а затем на 4 числа и пробел.

По крайней мере, это хорошее начало;)

PS: Есть много неправильных вещей о том, как сделать красивый.txt, содержащий вопросы и т.д.

  1. Сложнее разобрать
  2. Он больше по размеру

Вы могли бы, например, изменить *Foot-and-mouth на (*)Foot-and-mouth чтобы указать, что это ответ, а не два дополнительных строки для него;)

  • 0
    Причиной, по которой текстовый файл такой, является то, как я нашел его в Интернете. Я бы не сделал такой как обычно.
  • 0
    Oki oki;) В любом случае, вы можете разобрать это так или создать первую программу для изменения формата (может быть хорошей идеей, если файл становится больше)
Показать ещё 5 комментариев
1

Внедрите простой FSM и проанализируйте его по строкам. Читайте, пока вы не найдете строку, которая начинается с #dddd, а затем прочитать, пока вы не найдете строку, которая начинается с -. Эти строки составляют вопрос. Прочитайте до тех пор, пока не найдете строку, начинающуюся с *, затем прочитайте, пока не нажмете пустую строку. Это ваш выбор. Затем прочитайте, пока не найдете строку, которая начинается с Answer, на ваш ответ. Повторение.

  • 1
    Кажется, лучше, чем ответ только по ссылке.
  • 0
    Основываясь на этой схеме синтаксического анализа, файл можно сделать намного более компактным. Это зависит от того, насколько ОП хочет файл (если он хочет иметь возможность оставлять комментарии или что-то в этом роде)
0

Если каждый ваш вопрос занимает ровно 10 строк в файле, он просто просто анализирует его по очереди, получая среднее значение для каждой записи из своей позиции, а не для содержимого:

public class Parse {
    public static final int OPTION_PREFIX_LENGTH = "*".length();
    public static final int ANSWER_PREFIX_LENGTH = "Answer: ".length();
    public static final String QUESTION_SEPARATOR = "-----------------------------------------------------------------------------";

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("/Users/Marboni/tmp/test.txt"));

        try {
            while (br.ready()) {
                br.readLine();                                     // Skip separator (----).

                StringBuilder questionBuilder = new StringBuilder();
                String questionLine;
                while (!QUESTION_SEPARATOR.equals(questionLine = br.readLine())) {  // Reading lines and add them to question until separator.
                    questionBuilder.append(questionLine.trim()).append(' ');
                }
                String questionText = questionBuilder.toString().trim();
                String a = parseQuestion(br.readLine());           // Option a).
                String b = parseQuestion(br.readLine());           // Option b).
                String c = parseQuestion(br.readLine());           // Option c).
                String d = parseQuestion(br.readLine());           // Option d).
                br.readLine();                                     // Skip blank line.
                String answer = parseAnswer(br.readLine());        // Answer.

                if (br.ready()) {
                    br.readLine();                         // Skip blank line between questions, if exists.
                }

                Question question = new Question(questionText,
                        new Question.Answer(a, answer.equals(a)),
                        new Question.Answer(b, answer.equals(b)),
                        new Question.Answer(c, answer.equals(c)),
                        new Question.Answer(d, answer.equals(d))
                        );

                // Do something with it.
            }
        } finally {
            br.close();
        }
    }

    private static String parseQuestion(String record) {
        return record.trim().substring(OPTION_PREFIX_LENGTH);
    }

    private static String parseAnswer(String record) {
        return record.trim().substring(ANSWER_PREFIX_LENGTH);
    }
}
  • 0
    Привет, спасибо или твой ответ. К сожалению, я забыл включить некоторые вопросы, которые занимают две строки в файле.
  • 0
    @Wilson, обновлен для работы с многострочными вопросами.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню