删除所有非单词字符除外&&或'模式

时间:2013-02-14 18:16:02

标签: java regex

我正在尝试清除所有非单词字符的字符串,除非它是&即模式可能类似于&[\w]+;

例如:

abc; => abc
abc & => abc &
abc& => abc  

如果我使用string.replaceAll("\W",""),它会从我不想要的第二个示例中移除;'&'

在这个问题中使用否定预测可以提供快速解决方案正则表达式模式吗?

3 个答案:

答案 0 :(得分:2)

我不确定你是否可以使用简单的String.replaceAll来做到这一点。你应该使用PatternMatcher来循环匹配,有效地进行手动搜索和替换。类似下面的代码应该可以解决问题。

public String replaceString(String origString) {
    Pattern pattern = Pattern.compile("&(\w+);|[^\w]");
    Matcher matcher = pattern.matcher(origString);
    StringBuffer sb = new StringBuffer();
    while (matcher.find()) {
        if (matcher.group().startsWith("&") && !matcher.group(1).equals("amp")) {
            matcher.appendReplacement(sb, matcher.group());
        } else {
            matcher.appendReplacement(sb, "");
        }
    }
    matcher.appendTail(sb);
    return sb.toString();
}

答案 1 :(得分:2)

首先,我真的很喜欢这个问题。现在,单个replaceAll无法完成您想要的任务,因为为此,我们需要一个长度可变的negative look-behind,这是不允许的。如果它被允许,那就不会那么困难了。

无论如何,由于单replaceAll这里没有选项,你可以在这里使用一点点。就像首先替换你semi-colon的最后一个entity reference一样,使用一些字符序列,你确定它不会出现在字符串的其余部分,例如XXX或其他任何字符序列。我知道这不正确,但你肯定无法帮助它。

所以,这是你可以尝试的:

String str = "a;b&c &";

str  = str.replaceAll("(&\\w+);", "$1XXX")
          .replaceAll("&(?!\\w+?XXX)|[^\\w&]", "")
          .replaceAll("(&\\w+)XXX", "$1;");

System.out.println(str);

<强>解释

  • 第一个replaceAll,将&amp;模式替换为&ampXXX,或替换为上一个;的任何其他序列。
  • 第二个替换所有,替换任何&后面没有\\w+XXX或任何non-word, non &字符。这将替换不属于&'s种模式的所有&amp;。另外,还会替换任何其他非单词字符。
  • 第三个替换所有人,用XXX重新替换;,从&amp;
  • 创建回&ampXXX

为了便于理解,您可以使用PatternMatcher类,而且只要替换条件复杂,我就更愿意使用它们。

String str = "a;b&c &amp;";

Pattern pattern = Pattern.compile("&\\w+;|[^\\w]");
Matcher matcher = pattern.matcher(str);

StringBuilder sb = new StringBuilder();

while (matcher.find()) {
    String match = matcher.group();
    if (!match.matches("&\\w+;")) {
        matcher.appendReplacement(sb, "");
    } else {
        matcher.appendReplacement(sb, match);
    }
}
matcher.appendTail(sb);
System.out.println(sb.toString());

这个类似于@ Eric的代码,但是对它的概括。如果对&amp;进行了改进以删除其中的NullPointerException,那么该版本仅适用于{{1}}。

答案 2 :(得分:0)

我建议你使用这样的负面预测:

string.replace(/&(?!\w+;)/ig, '');

取代所有&amp;后面跟着一个以分号结尾的单词。

EDIT(Java):

string.replaceAll("/&(?!\w+;)/i", '');