Почему не работает regex в hasNext()

Мне нужно удалить слова с заданной длиной и чтобы начинались с согласной буквы, сделал через pattern и macher, кажется работает, но почему-то через Scanner не хочет.

File file = new File("src/text.txt");
StringBuilder result = new StringBuilder();
try {
    Scanner sc = new Scanner(file);
    while (sc.hasNext()) {
        if(!sc.hasNext(String.format("(^[b-df-hj-np-tv-zB-DF-HJ-NP-TV-Z])([a-zA-Z]){%s}[,. !]*$", length - 1))) {
            result.append(sc.next()).append(" ");
        }
    }
    sc.close();
} catch (FileNotFoundException e) {
    System.out.println("File " + file.getName() + " not found");
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(result);

Ответы (1 шт):

Автор решения: Alex Rudenko

Через сканер не хочет работать потому что возникает бесконечный цикл из-за того, что не пропускается "неподходящая" строка.

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

Его можно слегка исправить:

String.format("(?i)[B-Z&&[^EIOU]]([A-Z]){%s}[\\s\\p{Punct}]?", length - 1))
  • (?i) - не учитывать регистр при сравнении
  • [B-Z&&[^EIOU]] - сокращенная форма для всех согласных букв в латинице
  • [\\s\\p{Punct}]? - после слова может опционально идти пробел или знак пунктуации

Также следует использовать try-with-resources, чтобы сканер закрывался автоматически.

Исправленный пример:

String data = "One two three four! Let's run, foo, moo and boo: loo";

int length = 3;
StringBuilder result = new StringBuilder();
try (Scanner sc = new Scanner(data)) {
    while (sc.hasNext()) {
        if(!sc.hasNext(String.format("(?i)[B-Z&&[^EIOU]]([A-Z]){%s}[\\s\\p{Punct}]?", length - 1))) {
            result.append(sc.next()).append(" ");
        } else {
            System.out.println("Skipping: " + sc.next());
        }
    }
}
System.out.println(result);

Вывод:

Skipping: two
Skipping: run,
Skipping: foo,
Skipping: moo
Skipping: boo:
Skipping: loo
One three four! Let's and 
→ Ссылка