Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有效地从字符串中删除字符_Java_String - Fatal编程技术网

Java 有效地从字符串中删除字符

Java 有效地从字符串中删除字符,java,string,Java,String,这听起来可能是一个非常简单的问题,但是如何从一个字符串中删除多个不同的字符,而不必为每个字符都写一行,这正是我辛苦完成的工作。我在下面编写了一个字符串示例: String word = "Hello, t-his is; an- (example) line." word = word.replace(",", ""); word = word.replace(".", ""); word = wo

这听起来可能是一个非常简单的问题,但是如何从一个字符串中删除多个不同的字符,而不必为每个字符都写一行,这正是我辛苦完成的工作。我在下面编写了一个字符串示例:

            String word = "Hello, t-his is; an- (example) line."

            word = word.replace(",", "");
            word = word.replace(".", "");
            word = word.replace(";", "");
            word = word.replace("-", "");
            word = word.replace("(", "");
            word = word.replace(")", "");
            System.out.println(word);
这将产生“
Hello这是一个示例行”
”。一种更有效的方法是不使用(ab)regex,我会这样做:

String word=“您好,这是一个-(示例)行。”;
字符串“,.;-()”;
int len1=不需要的.length();
int len2=单词长度();
StringBuilder sb=新的StringBuilder(len2);
外部:用于(int j=0;j
优势在于性能。您不需要创建和解析正则表达式的开销

您可以将其封装在一个方法中:

public static String removeCharacters(String word, String undesirable) {
    int len1 = undesirable.length();
    int len2 = word.length();

    StringBuilder sb = new StringBuilder(len2);
    outer: for (int j = 0; j < len2; j++) {
        char c = word.charAt(j);
        for (int i = 0; i < len1; i++) {
            if (c == undesirable.charAt(i)) continue outer;
        }
        sb.append(c);
    }
    return sb.toString();
}

public static String removeSpecialCharacters(String word) {
    return removeCharacters(word, ",.;-()");
}
下面是一个性能测试:

公共类WordTest{
公共静态void main(字符串[]args){
整数迭代次数=10000000;
long t1=System.currentTimeMillis();
对于(int i=0;i
我的机器上的输出:

不带正则表达式,但使用复制的数组:5880
使用预编译正则表达式:11011
不带正则表达式,但使用字符串:3844
使用


请注意,特殊字符
-
(连字符)应使用双反斜杠进行转义,否则会被视为构造一个范围。

您可以尝试将正则表达式与Java的String.replaceAll方法一起使用:

word = word.replaceAll(",|\.|;|-|\(|\)", "");
如果您不熟悉正则表达式,|表示“或”。所以我们基本上是说,或者。或或-或(或)

请参阅更多:

编辑:

如前所述,我以前的版本不会编译。为了正确起见(尽管有人指出这不是最佳解决方案),下面是我的正则表达式的正确版本:

word = word.replaceAll(",|\\.|;|-|\\(|\\)", "");

这里有一个解决方案,以尽可能少的努力做到这一点;
toRemove
字符串包含您不希望在输出中看到的所有字符:

public static String removeChars(final String input, final String toRemove)
{
    final StringBuilder sb = new StringBuilder(input.length());
    final CharBuffer buf = CharBuffer.wrap(input);

    char c;

    while (buf.hasRemaining()) {
        c = buf.get();
        if (toRemove.indexOf(c) == -1)
            sb.append(c);
    }

    return sb.toString();
}
如果您使用Java 8,您甚至可以使用它(不幸的是,没有
CharStream
,因此强制转换是必要的…):


虽然没有比您可以使用的原始
replace
技术更有效

word = word.replaceAll("\\p{Punct}+", "");

要使用一个使用
replaceAll
的简单表达式来替换更大范围的字符

请尝试使用String的
replaceAll
方法-您提前知道必须删除的字符列表吗?如果我没有弄错的话,正则表达式是在编译时计算的,而不是在运行时。当字符串实际针对正则表达式进行测试时,正则表达式已转换为一个巨大的表,测试速度非常快。
.tocharray()
复制字符串的内部数组;这里最好使用
CharBuffer.wrap()
从中获取();您只需执行10000次操作,这正是Hotspot在决定对其进行优化之前运行某些代码的次数…@fge现在更好了吗
CharBuffer
只需将其委托给引擎盖下的
charAt
方法,因此直接转到
String
@AaronSmith查看我的性能测试就更容易了。我邀请你也在你的机器上试一下。那是相当浪费的;您可以在一个简单的字符类就足够的地方使用一个替换。而且,这甚至不会编译。为什么要在regexp中附加“+”(加号)?@Reimeus,加号很好。用空字符串替换整个匹配字符只是将每个匹配字符单独替换为空字符串的一种更有效的方法。如果要删除可变的字符列表,对“字符串”中的连字符进行转义的最聪明的方法是什么?好的,找到它:
public static String removeChars(final String input, final String toRemove)
{
    final StringBuilder sb = new StringBuilder(input.length());

    input.chars().filter(c -> toRemove.indexOf((char) c) == -1)
        .forEach(i -> sb.append((char) i));

    return sb.toString();
}
word = word.replaceAll("\\p{Punct}+", "");