#java #regex #java.util.scanner
#java #регулярное выражение #java.util.scanner
Вопрос:
Я пытаюсь создать программу, которая расшифровывает текстовый файл в читаемый текст. Закодированный текст следует двум правилам, он всегда начинается либо с гласной, либо с согласной, это представлено как C или V, за которым следует его позиция в индексе (например: V1C1C3, будет «abc»)
Я создал два массива, содержащих гласные и согласные («0» имеет индекс 0, чтобы остальная часть массива могла начинаться с index1):
String[] vowels = {"0", "a", "A", "e", "E", "i", "I", "o", "O", "u", "U", "y", "Y"};
String[] cons = {"0","b", "B", "c", "C", "d", "D", "f", "F", "g", "G", "h", "H", "j", "J", "k", "K", "l", "L", "m", "M", "n", "N", "p", "P", "q", "Q", "r", "R", "s", "S", "t", "T", "v", "V", "w", "W", "x", "X", "z", "Z"};
Я использую сканер для разделения кода на гласные и согласные, а также для получения значения индекса:
while(scan.hasNext()){
String[] parts = scan.nextLine().split("(?=[CV])");
for (String part : parts) {
Scanner num = new Scanner(part).useDelimiter("[^0-9] ");
int value = num.nextInt();
if(part.charAt(0) == 'C'){
System.out.print(cons[value]);
}
else if (part.charAt(0) == 'V'){
System.out.print(vowels[value]);
}
}
}
Зашифрованный текст: V6 C17V7C33V3 V1C23C23C17V3C29 (результат должен быть: я люблю яблоки)
Результат, который я получаю: Iloveapples
P.S: если у меня несколько абзацев зашифрованного текста, сканер останавливается после первого и выдает ошибку. Этого не произойдет, если я использую «scan.next ()» вместо «scan.nextLine ()»
Комментарии:
1. В коде нет ничего, что могло бы обнаружить и вывести недостающие пробелы.
2. @AdrianHHH Итак, вы бы предложили мне создать новый сканер для проверки пробелов или добавить «\ s» в уже существующий сканер?
3. Вам нужен еще один цикл вокруг вашего цикла parts. Выполните разделение на пробелы, затем передайте этот вывод в цикл parts . Выведите пробел в конце вашего нового цикла. В качестве альтернативы вы можете использовать streams или regex для переназначения ваших символов и сохранения пробелов.
Ответ №1:
Кажется, вы хотите, чтобы любая часть, которая не является кодировкой, оставалась неизменной, например, пробелы в приведенном примере, но также могут быть символами, такими как запятые, вопросительные знаки и т.д.
Это означает, что было бы намного лучше использовать замену регулярных выражений, используя регулярные выражения для поиска кодировок, то есть букв C
или V
цифр.
private static final String VOWELS = "aAeEiIoOuUyY";
private static final String CONSONANTS = "bBcCdDfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
// Requires Java 9
public static String decode(String encodedText) {
return Pattern.compile("[CV]\d ").matcher(encodedText)
.replaceAll(r -> String.valueOf((r.group().charAt(0) == 'V' ? VOWELS : CONSONANTS)
.charAt(Integer.parseInt(r.group().substring(1)) - 1)));
}
// For Java 1.4
public static String decode(String encodedText) {
StringBuffer buf = new StringBuffer();
Matcher m = Pattern.compile("[CV]\d ").matcher(encodedText);
while (m.find()) {
String token = m.group();
int value = Integer.parseInt(token.substring(1));
char ch = (token.charAt(0) == 'V' ? VOWELS : CONSONANTS).charAt(value - 1);
m.appendReplacement(buf, String.valueOf(ch));
}
return m.appendTail(buf).toString();
}
Тест
System.out.println(decode("V6 C17V7C33V3 V1C23C23C17V3C29"));
System.out.println(decode("C30C11V3 V1C29C15V3C5, "C36C11V1C31 V1C27V3 V11V7V9 C5V7V5C21C9?""));
Вывод
I love apples
She asked, "What are you doing?"
Для полноты картины, вот простой неоптимизированный метод кодирования, используемый для создания этого второго примера выше:
// For Java 1.5
public static String encode(String plainText) {
int index;
StringBuilder buf = new StringBuilder();
for (int i = 0; i < plainText.length(); i ) {
char ch = plainText.charAt(i);
if ((index = VOWELS.indexOf(ch)) != -1)
buf.append('V').append(index 1);
else if ((index = CONSONANTS.indexOf(ch)) != -1)
buf.append('C').append(index 1);
else
buf.append(ch);
}
return (buf.length() == plainText.length() ? plainText : buf.toString());
}
Ответ №2:
Первая часть этого кодирует некоторые тестовые фразы. Вторая часть декодирует их, сохраняя знаки препинания.
String[] vowels = { "0", "a", "A", "e", "E", "i", "I", "o",
"O", "u", "U", "y", "Y" };
String[] cons = { "0", "b", "B", "c", "C", "d", "D", "f", "F",
"g", "G", "h", "H", "j", "J", "k", "K", "l", "L", "m",
"M", "n", "N", "p", "P", "q", "Q", "r", "R", "s", "S",
"t", "T", "v", "V", "w", "W", "x", "X", "z", "Z" };
String c = String.join("", cons);
String v = String.join("", vowels);
String[] testData = { "I Love Applesn",
"To be or not to be that is the question!n",
"This also handles (parens) and `single` and "double" quotesn" };
// this section iterates over the phrases and encodes them, storing the values in
// a StringBuilder
List<String> coded = new ArrayList<>();
for (String text : testData) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length(); i ) {
char ch = text.charAt(i);
int index = v.indexOf(ch);
if (index >= 0) {
sb.append("V").append(index);
continue;
}
index = c.indexOf(ch);
if (index >= 0) {
sb.append("C").append(index);
continue;
}
sb.append(ch);
}
coded.add(sb.toString());
}
for (String code : coded) {
System.out.println(code);
}
// Now simply search on encoded values or a single character. Keep finding the
// pattern and converting back to a letter. Punctuation is preserved.
String pat = "([CV]\d |.)";
for (String code : coded) {
StringBuilder plain = new StringBuilder();
Matcher m = Pattern.compile(pat).matcher(code);
while (m.find()) {
String group = m.group();
if (group.charAt(0) == 'V') {
plain.append(v.charAt(
Integer.valueOf(group.substring(1))));
} else if (group.charAt(0) == 'C') {
plain.append(c.charAt(
Integer.valueOf(group.substring(1))));
} else {
plain.append(group);
}
}
System.out.println(plain);
}
Приведенное выше печатает сначала закодированные строки, затем декодированные строки.
V6 C18V7C33V3 V2C23C23C17V3C29
C32V7 C1V3 V7C27 C21V7C31 C31V7 C1V3 C31C11V1C31 V5C29 C31C11V3 C25V9V3C29C31V5V
7C21!
C32C11V5C29 V1C17C29V7 C11V1C21C5C17V3C29 (C23V1C27V3C21C29) V1C21C5 `C29V5C21C9
C17V3` V1C21C5 "C5V7V9C1C17V3" C25V9V7C31V3C29
I Love Apples
To be or not to be that is the question!
This also handles (parens) and `single` and "double" quotes