使用单个replaceAll删除所选单词(用****替换它们)?

时间:2010-06-03 13:05:04

标签: java regex

我想通过用“*”替换单词中的每个字符来审查字符串中的一些单词。基本上我想做

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

以便生成的s等于"lorem ***** dolor ***"

我知道如何通过重复的replaceAll调用来做到这一点,但我想知道,这可能与单个replaceAll有关吗?​​


更新:这是研究案例研究的一部分,原因基本上是我想要使用单行程,因为它简化了生成的字节码。这不是一个严肃的网页或任何东西。

4 个答案:

答案 0 :(得分:4)

可以使用zero-width lookarounds

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 ***

生成的正则表达式并不漂亮但它可以解决问题: - )

答案 1 :(得分:4)

这是对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

答案 2 :(得分:3)

这不是审查文本的好方法。杰夫阿特伍德以这种方式发表关于审查的文章。

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

除非你要花很多时间在这个审查功能上,否则最终可能会审查不应该的事情。

另一个注意事项:
将Java代码转换为1行代码不一定会简化字节码。使用该逻辑,您可以将审查代码放入单个方法中,然后使用它。

答案 3 :(得分:2)

Java的replace方法不将回调作为参数;所以这并不容易。但由于亵渎过滤器主要用于网络,我认为你可以使用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