如何缩短这段正则表达式代码?

时间:2013-05-31 17:30:36

标签: java regex

我在Java中有以下函数,它接受一个String注释并返回注释,但是所有尾随的#字符和任何#个字符在它们删除后都有一个空格,以及任何序列多个相邻的主题标签(例如###)替换为单个#个字符。这是代码段

private static String replaceHashTagsAndPunctuation(String comment) {
// Remove trailing '#' values
comment = comment.replaceAll("#*$", "");

// Replace instances of multiple '#' values with one '#'
comment = comment.replaceAll("#+", "#");


// Remove punctuation
comment = comment.replaceAll("[^a-zA-Z0-9 #]", "");

// Remove all hashtags that have no word after them
comment = comment.replaceAll("# ", "");

return comment;
}

这令人难以置信的冗长和丑陋。所以我的问题是:
如何使用更好的正则表达式语句重写它以在一行或两行中删除String的所有这些部分? 此外,解释为什么你建议的正则表达式代码可以帮助我更好地理解正则表达式如何在Java中工作。

4 个答案:

答案 0 :(得分:1)

创意1

如何更换两个来电:

comment = comment.replaceAll("#+([ #])", $1);

通过在那里留下尾随空格,它与你的两个略有不同:

comment = comment.replaceAll("#+", "#");
comment = comment.replaceAll("# ", "");

我不知道尾随空格是否重要,因为你的话说“删除任何带有空格的#”,但没有说删除空格。但是,代码会删除它。

创意2

它增加了一些复杂性,但您可以使用以下方法处理其中的三个:

comment = comment.replaceAll("#+([ #]|$)", $1);

<强>解释

第二个参数中的$1表示您将匹配的字符串替换为与括号内的部分匹配的匹配字符串。

[ #]表示空格或数字符号。

[# ]|$一起表示空格,数字符号或字符串的结尾。

答案 1 :(得分:1)

代码本身没有任何错误,但它可能是分解的。

例如:

// LinkedHashMap: insertion order matters!
private static final Map<Pattern, String> REPLACEMENTS
    = new LinkedHashMap<Pattern, String>();

static {
    Pattern pattern;
    String replacement;

    pattern = Pattern.compile("#*$");
    replacement = "";
    REPLACEMENTS.put(pattern, replacement);

    pattern = Pattern.compile("#+");
    replacement = "#";
    REPLACEMENTS.put(pattern, replacement);

    // etc
}

然后你的代码可能是:

private static String replaceHashTagsAndPunctuation(final String comment)
{
    String ret = comment;

    for (final Map.Entry<Pattern, String> entry: REPLACEMENTS.entrySet())
        ret = entry.getKey().matcher(ret).replaceAll(entry.getValue());

    return ret;
}

答案 2 :(得分:0)

你可以只清理一次:

comment = comment.replaceAll("#+", "#").replaceAll("[^a-zA-Z0-9 #]|# |#*$", "");

正则表达式中的栏表示OR

答案 3 :(得分:0)

嗯,首先,我认为你的起始正则表达是清晰,易懂和可靠的,这在正则表达式中是罕见且有价值的特性,所以如果我在代码中看到这个我正在努力我不会改变它。李的单线:

comment = comment.replaceAll("#+([ #]|$)", $1);

紧凑,正确,聪明,但乍一看很难理解。虽然我认为自己是正则表达式的一个wiz,但我仍然需要停下来思考并解包正则表达式中编码的3个案例,以弄清楚它将要做什么。

如果您希望在没有达到极端条件的情况下完善您的代码,我建议:

// Replace instances of 1 or more consecutive '#' values with a single '#'
comment = comment.replaceAll("#{1,}", "#");  // 1

// Strip out '#' followed by space or at end of line
comment = comment.replaceAll("#( |$)", "");  // 2
  1. 用一个“#”替换1个或多个“#”
  2. 删除“#”后跟空格或行尾。这也删除了“#”后的单个尾随空格。要保留空间,请将替换更改为“$ 1”。