Почему не работает 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