用 Java 中字符串中的特殊字符替换单词

Replace word with special characters from string in Java

我正在编写一种方法,该方法应将与列表中的单词匹配的所有单词替换为“****”

个字符。到目前为止,我有有效的代码,但所有特殊字符都被忽略了。

我试过用 "\\W" 在我的表达中,但看起来我没有很好地使用它,所以我可以使用一些帮助。

这是我目前的代码:

        for(int i = 0; i < badWords.size(); i++) {
        if (StringUtils.containsIgnoreCase(stringToCheck, badWords.get(i))) {
            stringToCheck = stringToCheck.replaceAll("(?i)\b" + badWords.get(i) + "\b", "****");
        }
    }

例如我有单词列表 ['bad', '@$$']。

如果我有一个字符串:"This is bad string with @$"
我期待这个方法 return "This is **** string with ****"

请注意,该方法应注意区分大小写的单词,例如TesTtest 应该处理相同。

我不知道你为什么要使用StringUtils你可以直接替换匹配坏词的词。此代码对我有用:

public static void main(String[] args) {
    ArrayList<String> badWords = new ArrayList<String>();
    badWords.add("test");
    badWords.add("BadTest");
    badWords.add("\$\$");
    String test = "This is a TeSt and a $$ with Badtest.";
    for(int i = 0; i < badWords.size(); i++) {
            test = test.replaceAll("(?i)" + badWords.get(i), "****");
    }
    test = test.replaceAll("\w*\*{4}", "****");
    System.out.println(test);
}

输出:

This is a **** and a **** with ****.

问题是这些特殊字符,例如$ 是正则表达式控制字符而不是文字字符。您需要使用两个反斜杠对坏词中出现的以下字符进行转义:

{}()\[].+*?^$|

我猜你的坏词列表包含特殊字符,这些字符在用正则表达式解释时具有特定含义(这就是 replaceAll 方法的作用)。例如,$ 通常匹配 string/line 的末尾。所以我建议结合使用:

  • 不要使用containsIgnoreCase来确定是否需要进行替换。每次都让 replaceAll 运行 - 如果没有匹配到坏词列表,则不会对字符串进行任何操作。

  • $这样在正则表达式中有特殊含义的字符,在加入坏词列表时需要进行转义。例如,badwords.add("@\$\$");

尝试这样的事情:

    String stringToCheck = "This is b!d string with @$$";
    List<String> badWords = asList("b!d","@$$");
    for(int i = 0; i < badWords.size(); i++) {
        if (StringUtils.containsIgnoreCase(stringToCheck,badWords.get(i))) {
            stringToCheck = stringToCheck.replaceAll("["+badWords.get(i)+"]+","****");
        }
    }
    System.out.println(stringToCheck);

另一种解决方案:与词边界匹配的错误词(不区分大小写)。

    Pattern badWords = Pattern.compile("\b(a|b|ĉĉĉ|dddd)\b",
            Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
    String text = "adfsa a dfs bb addfdsaf ĉĉĉ adsfs dddd asdfaf a";
    Matcher m = badWords.matcher(text);
    StringBuffer sb = new StringBuffer(text.length());
    while (m.find()) {
        m.appendReplacement(sb, stars(m.group(1)));
    }
    m.appendTail(sb);
    String cleanText = sb.toString();
    System.out.println(text);
    System.out.println(cleanText);
}

private static String stars(String s) {
    return s.replaceAll("(?su).", "*");
    /*
    int cpLength = s.codePointCount(0, s.length());
    final String stars = "******************************";
    return cpLength >= stars.length() ? stars : stars.substring(0, cpLength);
    */
}

然后(在评论中)正确计数的星星:一颗星表示 Unicode 代码点,给出两个代理对(两个 UTF-16 字符)。