从字符串中删除特定字符

22

我考虑使用String.replaceAll()方法来删除字符串中的某些字符。不清楚要删除哪些字符(即想要删除哪些字符),但我会假设任何字符都是有效的(例如[a-zA-Z]和像$%!这样的字符等)。

我看到了http://www.java-tips.org/java-se-tips/java.lang/strip-certain-characters-from-a-string.html,但肯定有更好的方法,而不是迭代每个字符...

您对此有什么想法吗?

谢谢

示例:

为了澄清一下,我的字符串长度会变化。我想从它中删除字符,确切的字符在运行时确定,并返回结果字符串。

以上面的段落为例,如果我要剔除“,.”,我将返回以下字符串:

Just to clarify I will have strings of varying lengths I want to strip characters from it the exact ones to be determined at runtime and return the resulting string

顺便提一下,我知道replaceAll()使用正则表达式,所以如果我想剔除字符"$,.",我需要将它们转义,对吗?


1
replaceAll会删除什么内容不清楚吗? - CromTheDestroyer
抱歉,我想要删除哪些字符不太清楚,而不是 removeAll() 将要替换哪些字符。 - ekawas
是的...我也不明白。你能发一个字符串和想要删除的字符的例子吗? - Josh M.
我不明白“在运行时确定确切的对象”会带来什么问题。你不必将字符串字面量传递给replaceAll。你可以将任何String对象放入其中。 - CromTheDestroyer
我主要担心正则表达式中的特殊字符,如$ ^ . ?等... - ekawas
显示剩余2条评论
8个回答

24

你可能需要先确定想要保留哪个字符,尝试类似以下的代码:

"mystring".replaceAll("[^a-zA-Z]", "")​

只保留字母。


最佳答案!简单而整洁! - Akshay Lokur

14

我猜下面的代码会帮助你。

    String input = "Just to clarify, I will have strings of varying "
      + "lengths. I want to strip characters from it, the exact "
      + "ones to be determined at runtime, and return the "
      + "resulting string.";
    String regx = ",.";
    char[] ca = regx.toCharArray();
    for (char c : ca) {
        input = input.replace(""+c, "");
    }
    System.out.println(input);

2
这肯定会影响性能。个人而言,我更喜欢下面采用的 StringBuilder 方法。 - John

11
这是那种情况之一,正则表达式可能不是一个好主意。你最终会写更多的特殊代码来绕过正则表达式,而比起这样,如果你采用简单的方法迭代字符,你还可以避免忽略一些可能在以后成为 bug 的情况。
如果你担心性能问题,正则表达式实际上会慢得多。如果你查看代码或分析其使用情况,正则表达式必须创建一个模式来解析/编译,通过匹配逻辑并应用替换。所有这些都会创建许多对象,如果你经常进行迭代,这可能是昂贵的。
我会稍微不同地实现你在那个链接中找到的东西。你可以在没有任何额外复杂性的情况下构建结果,从而节省不必要的字符串分配:String
public static String stripChars(String input, String strip) {
    StringBuilder result = new StringBuilder();
    for (char c : input.toCharArray()) {
        if (strip.indexOf(c) == -1) {
            result.append(c);
        }
    }
    return result.toString();
}

好的,John提供了一个避免正则表达式问题的好答案。String.replace(target, replacement)方法“用指定的字面替换序列替换此字符串的每个匹配字串目标序列”。 - WhiteFang34

11

如果你已经在使用Guava库,那么通过CharMatcher可以很容易地实现。

String charsToRemove = "%^#";
String stringToFilter = "I have 20% of my assets in #2 pencils! :^)";

String filtered = CharMatcher.anyOf(charsToRemove).removeFrom(stringToFilter);

看起来不错,但用哪个库? - trillions

2

我认为您正在寻找这样的代码来解决您的问题而不需要任何循环

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StripChars {
    public static void main(String[] args) {
    // prints: Just to clarify I will have strings of varying lengths   
    System.out.println(
     replace("Just to clarify, I will have strings of varying lengths.",
               ",."));

    // prints: Solution to my problem on Stackoverflow will cost me 0
    System.out.println(
     replace("Solution to my problem on stackoverflow will cost me $0.", 
               ".$"));      
    }

    static String replace(String line, String charsToBeReplaced) {
        Pattern p = Pattern.compile("(.{1})");
        Matcher m = p.matcher(charsToBeReplaced);
        return line.replaceAll(m.replaceAll("\\\\$1\\|"), "");
    }
}

为了处理输入替换方法中的特殊正则表达式字符(元字符),首先要在输入中的每个字符前面放置\(反斜杠),并在每个字符后面放置|(管道)。因此,输入",."将变为"\\,|\\.|"
完成这一步之后,替换就非常简单了:对于每个匹配的字符,用空格替换它。
虽然此解决方案中没有使用,但以下是检测Java中任何特殊正则表达式字符存在的模式:
Pattern metachars = Pattern.compile(
   "^.*?(\\(|\\[|\\{|\\^|\\-|\\$|\\||\\]|\\}|\\)|\\?|\\*|\\+|\\.).*?$");

2
我认为可以通过使用正则表达式来实现这个目标。
首先,我们知道[a-zA-Z]$%!是字符串中有效的字符。因此,我们使用正则表达式"[^a-zA-Z0-9$%!]"来去除其他无效字符。请参考JAVA模式的详细信息,链接:http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
接下来,我们可以使用mystring.replaceAll(String regex, String replacement)
附注:RefexPlanet在线正则表达式测试页面。

2
我认为这应该是被接受的答案,为什么要重新发明轮子呢! - ExistMe

1

0

我想你提供的链接中的示例代码已经足够好了,你可以添加其他有效字符来选择。但是你可以使用正则表达式来最小化代码量。可以查看 Abdullah 的代码,或者查看更多link1,link2, link3


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接