Цензура выбранных слов (замена их на ****) с использованием одной заменыВсе? - PullRequest
2 голосов
/ 03 июня 2010

Я хотел бы подвергнуть цензуре некоторые слова в строке, заменив каждый символ в слове на «*». В основном я хотел бы сделать

String s = "lorem ipsum dolor sit";
s = s.replaceAll("ipsum|sit", $0.length() number of *));

, так что результирующее s равно "lorem ***** dolor ***".

Я знаю, как сделать это с повторными replaceAll вызовами, но мне интересно, возможно ли это сделать с одним replaceAll?


Обновление: это часть исследования конкретного случая, и причина в основном в том, что я хотел бы избежать неприятностей с одной строкой, поскольку она немного упрощает сгенерированный байт-код. Это не для серьезной веб-страницы или чего-то еще.

Ответы [ 4 ]

5 голосов
/ 03 июня 2010

Вот модификация ответа 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.

4 голосов
/ 03 июня 2010

Это возможно, используя просмотр нулевой ширины :

public class Test {
    public static void main(String... args) {
        String s = "lorem ipsum dolor sit";
        System.out.println(s.replaceAll(censorWords("ipsum", "sit"), "*"));
    }

    public static String censorWords(String... words) {
        String re = "";
        for (String w : words)
            for (int i = 0; i < w.length(); i++)
                re += String.format("|((?<=%s)%s(?=%s))",
                        w.substring(0, i), w.charAt(i), w.substring(i + 1));
        return re.substring(1);
    }
}

Печать

lorem ***** dolor ***

Сгенерированное регулярное выражение не очень красиво, но оно делает свое дело: -)

3 голосов
/ 03 июня 2010

Это не хороший способ для цензуры текста. Джефф Этвуд написал замечательный пост о цензуре таким образом.

http://www.codinghorror.com/blog/2008/10/obscenity-filters-bad-idea-or-incredibly-intercoursing-bad-idea.html

Если вы не собираетесь тратить много и много времени на эту функцию цензуры, она, вероятно, в конечном итоге будет подвергать цензуре то, чего не должно быть.

Другое примечание:
Превращение кода Java в 1-строчный не обязательно упростит байт-код. Используя эту логику, вы можете бросить свой код цензуры в один метод, а затем просто использовать его.

2 голосов
/ 03 июня 2010

Java метод замены не принимает обратный вызов в качестве аргумента; так что это не легко. Но поскольку фильтры ненормативной лексики в основном используются в Интернете, я предполагаю, что для этого можно использовать JavaScript.

var s = "this is some sample text to play with";
var r = s.replace(/\b(some|sample|to)\b/g, function() {
  var star = "*";
  var len = arguments[1].length;
  while(--len)
    star += "*";
  return star;
});
console.log(r);//this is **** ****** text ** play with
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...