【问题标题】:Regex using Java String.replaceAll使用 Java String.replaceAll 的正则表达式
【发布时间】:2013-05-27 19:03:21
【问题描述】:

我正在寻找如下替换 java 字符串值。下面的代码不起作用。

        cleanInst.replaceAll("[<i>]", "");
        cleanInst.replaceAll("[</i>]", "");
        cleanInst.replaceAll("[//]", "/");
        cleanInst.replaceAll("[\bPhysics Dept.\b]", "Physics Department");
        cleanInst.replaceAll("[\b/n\b]", ";");
        cleanInst.replaceAll("[\bDEPT\b]", "The Department");
        cleanInst.replaceAll("[\bDEPT.\b]", "The Department");
        cleanInst.replaceAll("[\bThe Dept.\b]", "The Department");
        cleanInst.replaceAll("[\bthe dept.\b]", "The Department");
        cleanInst.replaceAll("[\bThe Dept\b]", "The Department");
        cleanInst.replaceAll("[\bthe dept\b]", "The Department");
        cleanInst.replaceAll("[\bDept.\b]", "The Department");
        cleanInst.replaceAll("[\bdept.\b]", "The Department");
        cleanInst.replaceAll("[\bdept\b]", "The Department");

实现上述替换的最简单方法是什么?

【问题讨论】:

  • 不工作是什么意思?
  • 删除方括号([])。这些用于字符类。如果其他方法不起作用,则需要更具体。
  • 字符串是不可变的
  • 和忽略大小写修饰符适用于很多 dept 替换
  • 正如@SLaks 所指出的:字符串是不可变的。如果您不将String.replaceAll() 的返回值存储在某处,您的代码将什么也不做。现在,您的代码对返回值没有任何作用。

标签: java regex string replaceall


【解决方案1】:

如果它是您不断使用的功能,则存在问题。每次调用都会重新编译每个正则表达式。最好将它们创建为常量。你可以有这样的东西。

private static final Pattern[] patterns = {
    Pattern.compile("</?i>"),
    Pattern.compile("//"),
    // Others
};

private static final String[] replacements = {
    "",
    "/",
    // Others
};

public static String cleanString(String str) {
    for (int i = 0; i < patterns.length; i++) {
        str = patterns[i].matcher(str).replaceAll(replacements[i]);
    }
    return str;
}

【讨论】:

  • 我们现在每次都创建 Matcher 对象,而不是 Pattern。这个怎么样?
  • 因为编译正则表达式模式比为(预编译的)模式创建匹配器成本更高?
【解决方案2】:
cleanInst.replaceAll("[<i>]", "");

应该是:

cleanInst = cleanInst.replaceAll("[<i>]", "");

因为String 类是不可变的并且不会改变其内部状态,即replaceAll() 返回一个不同于cleanInst 的新实例。

【讨论】:

    【解决方案3】:

    您应该阅读基本的regular expressions tutorial

    在此之前,您尝试做的事情可以这样完成:

    cleanInst = cleanInst.replace("//", "/");
    cleanInst = cleanInst.replaceAll("</?i>", "");
    cleanInst = cleanInst.replaceAll("/n\\b", ";")
    cleanInst = cleanInst.replaceAll("\\bPhysics Dept\\.", "Physics Department");
    cleanInst = cleanInst.replaceAll("(?i)\\b(?:the )?dept\\b\\.?", "The Department");
    

    您可能会链接所有这些替换操作(但我不知道正确的 Java 语法)。

    关于word boundaries\b 通常只在字母数字字符之前或之后才有意义。

    例如,\b/n\b 只会匹配 /n,前提是它的前面直接有一个字母数字字符,后跟一个非字母数字字符,因此它匹配 "a/n!",但不匹配 "foo /n bar"

    【讨论】:

    • +1 你的答案很好,但为什么“the”的非捕获组?仅仅是“表演”吗?因为恕我直言,可读性下降的幅度大于性能的提高。顺便说一句,我怀疑/n 应该是\n
    • 我只是习惯了这样。除非我想捕获一个组,否则我从不使用捕获括号。我同意清楚地表达自己的意图和可读性之间存在矛盾。
    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 2016-09-28
    相关资源
    最近更新 更多