Вот модификация ответа aioobe, использующая вложенные утверждения вместо вложенного цикла для генерации утверждений:
public static void main(String... args) {
String s = "lorem ipsum dolor sit blah $10 bleh";
System.out.println(s.replaceAll(censorWords("ipsum", "sit", "$10"), "*"));
// prints "lorem ***** dolor *** blah *** bleh"
}
public static String censorWords(String... words) {
StringBuilder sb = new StringBuilder();
for (String w : words) {
if (sb.length() > 0) sb.append("|");
sb.append(
String.format("(?<=(?=%s).{0,%d}).",
Pattern.quote(w),
w.length()-1
)
);
}
return sb.toString();
}
Некоторые ключевые моменты:
StringBuilder.append
в цикле вместо String +=
Pattern.quote
для экранирования $
или \
цензурированными словами
Тем не менее, это не лучшее решение проблемы. На самом деле, это просто забавная игра с регулярными выражениями.
Похожие вопросы
Как это работает
Мы хотим заменить на "*"
, поэтому мы должны соответствовать одному символу за раз. Вопрос в том, какой персонаж.
Это персонаж, который, если вы возвращаетесь достаточно долго, а затем смотрите вперед, вы видите цензурированное слово.
Вот регулярное выражение в более абстрактной форме:
(?<=(?=something).{0,N})
Это соответствует позициям, где, позволяя вам вернуться к N
символам, вы можете посмотреть вперед и увидеть something
.