Как получить "голый" текст, без маски?
Есть маска текста: xxx/13xx/xxx
Есть текст: 222/1300/777
Как я могу получить текст 22200777
?
.replace("/13", "")
отработает криво на примере 222/1300/135
Источник: Stack Overflow на русском
Есть маска текста: xxx/13xx/xxx
Есть текст: 222/1300/777
Как я могу получить текст 22200777
?
.replace("/13", "")
отработает криво на примере 222/1300/135
Через регулярные выражения: заменяем все иксы на (.)
, дальше матчим как регулярное выражение, вытаскиваем все группы:
String mask = "xxx/13xx/xxx";
var pattern = Pattern.compile("^" + mask.replace("x", "(.)") + "$");
String text = "222/1300/777";
var match = pattern.matcher(text);
if (match.find()) {
var stringBuilder = new StringBuilder();
for (int i = 1; i <= match.groupCount(); i++) {
stringBuilder.append(match.group(i));
}
String result = stringBuilder.toString();
System.out.println(result);
} else {
System.out.println("Ничего не найдено (строка не соответствует маске)");
}
Вывод:
22200777
Другой вариант - просто идем циклом, сравнивамем символы маски и текста, то что соответствует иксам - добавляем в результат (тут в коде получилось больше валидации, чем какой-то сложной логики):
private static String getByMask(String text, String mask) {
var result = new StringBuilder();
if (text.length() != mask.length()) {
throw new RuntimeException("Длина текста не соответствует маске");
}
for (int i = 0; i < mask.length(); i ++ ) {
if (mask.charAt(i) == 'x') {
result.append(text.charAt(i));
} else if (mask.charAt(i) != text.charAt(i)) {
throw new RuntimeException(
String.format("Символ на позиции %d ('%c') не соответствует маске (символ '%c')",
i, text.charAt(i), mask.charAt(i)));
}
}
return result.toString();
}
public static void main(String[] args) {
String mask = "xxx/13xx/xxx";
String text = "222/1300/777";
System.out.println(getByMask(text, mask));
}
Варианты с использованием Stream API и методами Matcher::results()
/ Matcher::replaceAll()
x
в маске превращаются в группы (.)
public static String checkMask1(String mask, String val) {
return Pattern.compile(mask.replaceAll("x", "(.)"))
.matcher(val)
.results() // Stream<MatchResult>
.flatMap(mr -> IntStream.rangeClosed(1, mr.groupCount())
.mapToObj(i -> mr.group(i))
) // Stream<String>
.collect(Collectors.joining());
}
При несоответствии шаблона возвращается пустая строка.
x
меняется на (.)
x
на "$1$2...$N" с использованием Matcher::replaceAll
, все символы не-x
удаляются.public static String checkMask2(String mask, String val) {
int[] ix = {1};
return val.replaceFirst(
mask.replaceAll("x", "(.)"),
Pattern.compile("x").matcher(mask.replaceAll("[^x]", ""))
.replaceAll(mr -> "\\$"+ix[0]++)
);
}
При несоответствии шаблона возвращается исходная строка
String[] tests = {"222/1300/777", "222/1400/777"};
for (String t : tests) {
System.out.println(t + " -> '" + checkMask1("xxx/13xx/xxx", t) + "'");
System.out.println(t + " -> '" + checkMask2("xxx/13xx/xxx", t) + "'");
}
222/1300/777 -> '22200777'
222/1300/777 -> '22200777'
222/1400/777 -> ''
222/1400/777 -> '222/1400/777'