代码之家  ›  专栏  ›  技术社区  ›  aioobe

用一个替换词检查选中的单词(用****替换它们)?

  •  2
  • aioobe  · 技术社区  · 14 年前

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

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

    所以结果 s 等于 "lorem ***** dolor ***" .

    我知道如何重复 replaceAll 调用,但我想知道, 这可以用单人间吗 替换所有 ?


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

    4 回复  |  直到 14 年前
        1
  •  4
  •   Community Ramakrishna.p    7 年前

    下面是对Aiobe答案的修改,使用嵌套断言而不是嵌套循环来生成断言:

    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 逃避任何 $ \ 用审查过的话

    也就是说,这不是解决问题的最佳方案。这只是一个有趣的雷鬼游戏,真的。

    相关问题


    它是如何工作的

    我们想换成 "*" ,所以我们必须一次匹配一个字符。问题是哪个角色。

    这是一个角色,如果你回到过去足够长的时间,然后你向前看,你会看到一个被审查过的词。

    下面是更抽象的regex:

    (?<=(?=something).{0,N})
    

    这与位置相匹配,允许您返回 N 人物,你可以向前看 something .

        2
  •  4
  •   aioobe    14 年前

    有可能使用 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 ***
    

    生成的正则表达式不漂亮,但它有以下功能:—)

        3
  •  3
  •   jjnguy Julien Chastang    14 年前

    这不是审查文本的好方法。杰夫·阿特伍德有一篇关于用这种方式审查的好文章。

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

    除非你要花大量的时间在这个审查功能上,否则最终可能会审查不该审查的东西。

    另一个注意事项:
    将Java代码转换成1-LILE将不必简化字节码。使用这个逻辑,你可以把你的审查代码扔到一个单一的方法中,然后使用它。

        4
  •  2
  •   Amarghosh    14 年前

    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