В настоящее время я изучаю свои навыки кодирования и работаю над некоторыми легкими проблемами, которые я нашел в Интернете. Конкретная задача состоит в том, чтобы ввести txt файл, содержащий любое количество строк, и чтобы программа проверила каждую строку и вернула "True" или "False" в зависимости от того, содержит ли эта строка все 26 букв алфавита. Я чувствую, что почти закончил, но мое регулярное выражение для соответствия строке [az] возвращает false независимо от того, что я делаю. Я попытался изменить строку на нижний регистр, удалив пробелы, и ничего не работает.
Текст, который у меня есть в моем текстовом файле, в настоящее время: "Быстрая коричневая лиса прыгает по ленивой собаке".
package easy139;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class easy139 {
public static void main(String[] args) {
try {
Scanner in = new Scanner(new FileReader("input.txt"));
while (in.hasNextLine()) {
String line = in.nextLine();
System.out.println(line);
String noSpaces = line.replaceAll(" ","");
if (noSpaces.matches("[a-z]")) {
System.out.println("True");
}
else {
System.out.println("False");
}
}
in.close();
} catch (IOException e) {
}
}
}
Ваш тест возвращает false, потому что regex [az]
означает "ровно одну букву".
String.matches()
выражение, которое работает с String.matches()
:
(?i)(?=.*a)(?=.*b)(?=.*c)...(?=.*z).*
Это использует один взгляд вперед для каждой буквы, каждый из которых утверждает, что письмо присутствует. Переключатель (?i)
включает чувствительность к регистру.
"abc".matches("(?i)(?=.*a)(?=.*b)(?=.*c)")
приводит к false
...
Вот решение на основе не регулярного выражения, если вы заинтересованы в нем:
public static void main(String[] args) throws Exception {
Set<Character> letters = new HashSet<>();
Scanner in = new Scanner(new FileReader("input.txt"));
try {
while (in.hasNextLine()) {
letters.clear();
for (char c : in.nextLine().toCharArray()) {
if (Character.isLetter(c)) letters.add(toLowerCase(c));
}
System.out.println(letters.size() == 26);
}
} finally { in.close(); }
}
Извлеките это в новый метод и зациклируйте на все символы:
static boolean containsAllCharacters(String line) {
if (line.length() < 26) {
// if string is less than 26 characters long,
// it won't hold all characters in it
return false;
}
for (char c = 'a'; c <= 'z'; c++) {
if (line.indexOf(c) == -1) {
return false;
}
}
return true;
}
Тогда вы можете называть его так:
String line = in.nextLine();
System.out.println(line);
System.out.println(containsAllCharacters(line) ? "TRUE" : "FALSE");
[az]
означает «один символ, содержащийся в диапазоне az (поэтому, в основном, буква)».[az]{26}
будет означать «26 букв», без каких-либо ограничений на какие буквы. Вам придется найти другой путь!