Например, у меня есть список слов, которые нужно замаскировать.
India
Australia
North America
South America
White House building
Мне нужен вывод, как показано ниже.
Ixxxa
Axxxxxxxa
Nxxxh Axxxxxa
Sxxxh Axxxxxa
Wxxxe Hxxxe bxxxxxxg
используя приведенное ниже выражение, я могу маскировать последние символы, включая пробелы.
return input.replaceAll("[\\s()]+", " ").replaceAll("\\d(?=(?:\\D*\\d){4})","X");
Может просто replaceAll("\\B\\w\\B", "x")
? Или replaceAll("\\B\\p{L}\\B", "x")
?
Если вы хотите сопоставить все непробельные символы, вы можете использовать обходные пути (?<=\S)\S(?=\S)
regex101.com/r/0gSM5x/1 См. ideone.com/nHEPiA
Я не уверен насчет регулярного выражения, если вы хотите сделать это ООП-способом, но, возможно, менее эффективным, вы можете разделить строки и слова и программно замаскировать каждое из них:
class MaskedText {
private final String maskedString;
private final char maskChar;
public MaskedText(String maskedString) {
this(maskedString, 'x');
}
public MaskedText(String maskedString, char maskChar) {
this.maskChar = maskChar;
this.maskedString = Arrays.stream(maskedString.split("\n"))
.map(this::maskLine)
.collect(Collectors.joining("\n"));
}
private String maskLine(String rawLine) {
return Arrays.stream(rawLine.split(" "))
.map(this::maskWord)
.collect(Collectors.joining(" "));
}
private String maskWord(String rawWord) {
return rawWord.charAt(0)
+ String.valueOf(maskChar).repeat(rawWord.length() - 2)
+ rawWord.charAt(rawWord.length() - 1);
}
@Override
public String toString() {
return maskedString;
}
}
И вы можете использовать его следующим образом:
@Test
void test() {
String txt = """
India
Australia
North America
South America
White House building
""";
MaskedText masked = new MaskedText(txt);
assertThat(masked.toString()).isEqualTo("""
"Ixxxa
Axxxxxxxa
Nxxxh Axxxxxa
Sxxxh Axxxxxa
Wxxxe Hxxxe bxxxxxxg"
""");
}
или прямо в логах: log.info("account: {}", new MaskedText(account))
Вышеприведенное предложение, опубликованное для использования ниже регулярного выражения, помогло решить проблему.
(?<=\S)\S(?=\S)
Я тестировал его как для символов, так и для чисел с разными комбинациями. Это решило мое требование... спасибо.
Чтобы сопоставить символ без пробелов, кроме «внешних», вы можете установить символ без пробелов \S
слева и справа справа:
(?<=\S)\S(?=\S)
В Яве
(?<=\\S)\S(?=\\S)
Посмотрите демонстрацию регулярных выражений и демонстрацию Java.
Пример Java:
String regex = "(?<=\\S)\\S(?=\\S)";
String string = "India\n"
+ "Australia\n"
+ "North America\n"
+ "South America\n"
+ "White House building\n"
+ "a\n"
+ "ab\n"
+ "abc\n"
+ "tthis123_isatest\n"
+ "!@#$%";
String result = string.replaceAll(regex, "x");
System.out.println(result);
Выход
Ixxxa
Axxxxxxxa
Nxxxh Axxxxxa
Sxxxh Axxxxxa
Wxxxe Hxxxe bxxxxxxg
a
ab
axc
txxxxxxxxxxxxxxt
!xxx%
Почему вы сопоставляете цифры? Есть только символ слова?
\B[a-z](?=[a-z]*[a-z]\b)
regex101.com/r/52OVyt/1