Почему readline не читает каждую строку - PullRequest
0 голосов
/ 23 марта 2019

Я пытаюсь найти (с помощью Regex) в большом текстовом файле первую строку, где вместо «True» стоит «False». В этом случае есть несколько строк.

Пример текстового файла:

test, test, test, True,
test, test, test, True,
test, test, test, False, (i want this line)
test, test, test, False,
test, test, test, True,
test, test, test, True,
test, test, test, False,(and that) 
test, test, test, False,
test, test, test, True,
test, test, test, True,

Я читаю файл построчно. Всегда, когда читаемая строка соответствует регулярному выражению «True», она читает следующую строку и пытается проверить, соответствует ли следующая строка регулярному выражению «False». Если так (пока), он должен напечатать мне строку.

try {
    BufferedReader br = 
    new BufferedReader(new FileReader(C:\\Directory\\test.txt)
    String lineRead;
    while ((lineRead = br.readLine()) != null) {
          if(lineRead.matches( ".*True.*")){
             if((lineRead = br.readLine()) != null){
                if((lineRead.matches( ".*False.*"))){
                   System.out.println(lineRead);
                }
             }
           }
    }
} 

Это дает мне большинство строк, но не все. Линии разделены на несколько тысяч. «Ложных» строк всегда несколько сотен, которые следуют. Так что не должно быть проблем с «перепрыгиванием».

Ответы [ 3 ]

2 голосов
/ 23 марта 2019

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

boolean flag = false;
while ((lineRead = br.readLine()) != null) {
    if (lineRead.matches(".*\\bTrue\\b.*")) {
        flag = true;
    }
    else if (lineRead.matches(".*\\bFalse\\b.*")) {
        if (flag) {
            System.out.println(lineRead);
            flag = false;
        }
    }
}

Логическое значение flag отслеживает состояние предыдущей строки.Мы печатаем только строку, содержащую false, если это будет первая строка false после предыдущей строки true.И, после анализа ложной строки, мы устанавливаем флаг в false, чтобы предотвратить печать второй ложной строки и далее.

0 голосов
/ 23 марта 2019

Отслеживание вашего исходного кода, с примером, который вы приводите, я вижу.строка 5: читает строку ввода 1строка 6: проходит, поэтому читает строку ввода 2строка 7: не удаетсястрока 5: читает строку ввода 3строка 6: не удаетсястрока 5: читает строку 4...Следовательно, первый набор «ложных» линий не будет отображаться, как и любой набор ложных линий, разделенных 2 «истинными» линиями.

0 голосов
/ 23 марта 2019

Другим более простым и менее подробным решением может быть следующее:

private static void findFalse() {
    try(var stream = Files.lines(Paths.get(PATH))) {
        stream.filter(PATTERN.asPredicate())
            .forEach(System.out::println);
    } catch (IOException e) {
        System.err.println("An error has occurred:: " + e.getMessage());
    }
}

Сначала начните с определения Pattern, например, так:

private static final Pattern PATTERN = Pattern.compile(".*\\bFalse\\b.*");

Затемпросто откройте поток строки файла, отфильтруйте, используя шаблон, который вы определили, и выведите каждую совпадающую строку в стандартный вывод.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...