Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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_Regex_String - Fatal编程技术网

在Java中有效地从字符串中删除特定字符(一些标点符号)?

在Java中有效地从字符串中删除特定字符(一些标点符号)?,java,regex,string,Java,Regex,String,在Java中,从字符串中删除给定字符的最有效方法是什么?目前,我有以下代码: private static String processWord(String x) { String tmp; tmp = x.toLowerCase(); tmp = tmp.replace(",", ""); tmp = tmp.replace(".", ""); tmp = tmp.replace(";", ""); tmp = tmp.replace("!"

在Java中,从字符串中删除给定字符的最有效方法是什么?目前,我有以下代码:

private static String processWord(String x) {
    String tmp;

    tmp = x.toLowerCase();
    tmp = tmp.replace(",", "");
    tmp = tmp.replace(".", "");
    tmp = tmp.replace(";", "");
    tmp = tmp.replace("!", "");
    tmp = tmp.replace("?", "");
    tmp = tmp.replace("(", "");
    tmp = tmp.replace(")", "");
    tmp = tmp.replace("{", "");
    tmp = tmp.replace("}", "");
    tmp = tmp.replace("[", "");
    tmp = tmp.replace("]", "");
    tmp = tmp.replace("<", "");
    tmp = tmp.replace(">", "");
    tmp = tmp.replace("%", "");

    return tmp;
}
私有静态字符串处理字(字符串x){
串tmp;
tmp=x.toLowerCase();
tmp=tmp.replace(“,”,”);
tmp=tmp.替换(“.”,”);
tmp=tmp.replace(“;”,“”);
tmp=tmp。替换(“!”,”);
tmp=tmp。替换(“?”,”);
tmp=tmp.replace(“(”,”);
tmp=tmp.replace(“)”,“);
tmp=tmp.replace(“{,”);
tmp=tmp.replace(“}”和“”);
tmp=tmp.replace(“[”,”);
tmp=tmp.replace(“]”,“”);
tmp=tmp.replace(“,”);
tmp=tmp.replace(“%”,“”);
返回tmp;
}

如果我使用某种StringBuilder、正则表达式或其他东西,会更快吗?是的,我知道:对它进行分析并查看,但我希望有人能给出他们的答案,因为这是一项常见的任务。

字符串是不可变的,因此尝试并动态使用它们并不好尝试使用StringBuilder而不是String,并使用其所有精彩的方法!它可以让你做任何你想做的事。另外,如果您有什么事情要做,请找出它的正则表达式,它将为您带来更好的效果。

您可以这样做:

tmp.replaceAll("\\W", "");
要删除标点符号

请使用
String#replaceAll(String regex,String replacement)
as

tmp = tmp.replaceAll("[,.;!?(){}\\[\\]<>%]", "");

System.out.println(
   "f,i.l;t!e?r(e)d {s}t[r]i<n>g%".replaceAll(
                   "[,.;!?(){}\\[\\]<>%]", "")); // prints "filtered string"
tmp=tmp.replaceAll(“[,.;!?(){}\\[\]%]”,“”);
System.out.println(
“f,i.l;t!e?r(e)d{s}t[r]ig%”(
"[,.;!?(){}\\[\\]%]", "")); // 打印“过滤字符串”

虽然
\\p{Punct}
将指定比问题中更宽的字符范围,但它允许更短的替换表达式:

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

你可以这样做:

static String RemovePunct(String input) 
{
    char[] output = new char[input.length()];
    int i = 0;

    for (char ch : input.toCharArray())
    {
        if (Character.isLetterOrDigit(ch) || Character.isWhitespace(ch)) 
        {
            output[i++] = ch;
        }        
    }

    return new String(output, 0, i);
}

// ...

String s = RemovePunct("This is (a) test string.");
如果您发现正则表达式因您的需要而变慢,那么它的性能可能会比使用正则表达式更好

然而,如果你有一个长长的、独特的、你想删除的特殊字符列表,它可能会很快变得一团糟。在这种情况下,正则表达式更容易处理


现在,您的代码将迭代
tmp
的所有字符,并将它们与要删除的所有可能的字符进行比较,因此它将使用
tmp字符数
x
要删除的字符数
比较

要优化代码,可以使用短路或
|
并执行以下操作

StringBuilder sb = new StringBuilder();
for (char c : tmp.toCharArray()) {
    if (!(c == ',' || c == '.' || c == ';' || c == '!' || c == '?'
            || c == '(' || c == ')' || c == '{' || c == '}' || c == '['
            || c == ']' || c == '<' || c == '>' || c == '%'))
        sb.append(c);
}
tmp = sb.toString();

这里有一个迟来的答案,只是为了好玩

在这种情况下,我建议以可读性为目标,而不是以速度为目标。当然,您可以非常可读,但速度太慢,就像在这个超级简洁的版本中:

private static String processWord(String x) {
    return x.replaceAll("[][(){},.;!?<>%]", "");
}
填充一次,然后迭代,生成结果字符串。我将把代码留给你。:)

再说一次,我不会深入研究这种优化。代码变得太难读了。性能有那么重要吗?还要记住,现代语言非常紧张,预热后它们的性能会更好,所以请使用一个好的分析器


应该提到的一点是,原始问题中的示例是高度非性能的,因为您正在创建一大堆临时字符串!除非编译器将所有这些都优化掉,否则该特定解决方案的性能将最差。

这也将删除空格。。。还有很多OP不想删除的字符,比如“
\W
代表任何不是字母、数字或下划线的字符!!!如果你能让正则表达式更具体一些就更好了。不,这不好。
[\W]
意味着
[^\a-Za-z_0-9]
,这意味着此解决方案还将删除类似
é的字母。
。至少使用一些尊重Unicode且不以ASCII为中心的字母!我看到有人对你投了反对票。这可能是因为作为注释比作为注释更好answer@sunrize920计票结果为+0/-0。未投下任何反对票。投票结果为removedI没有考虑到你没有足够的代表发表评论的事实。我只是讨厌人们否决投票,但不要对原因发表评论。
StringBuilder
在你从片段构建字符串时很好。通过正则表达式将字符串拆分成片段并重新组装可能是一个好策略。我相信
string.replaceAll
在内部执行类似的操作。一般来说,Java正则表达式的性能相当好,除非我做了一些对性能非常敏感的事情,否则我通常只使用m并继续。还有一个tmp.replaceAll(“\\W”,”)将删除字符串中的标点符号和空格。澄清要求:请定义标点符号的含义。是否只是上面列出的字符?em破折号如何?卷曲引号如何?非英语语言的引号符号如何?下次您可能会自己找到有关正则表达式的解决方案。此外,这可能对你也有帮助@Pshemo这里没有直接的答案。但这将有助于理解而不是复制..下次他可能会找到解决这类问题的方法。我从来没有说过这将是答案。我说这可能对你有帮助您尝试过
\p{p}
捕获非ASCII标点符号?
P
是标点符号的Unicode类别。嗯,尝试过,但它留下了一些原始字符(例如
),因此将坚持如下:)您认为“\\P{Punct}”的实现会比只指定[,!{}](和其他字符)更有效吗,作为一个字符类?@RayToal事实上,我是OP。我澄清了这个问题,希望你现在能看得更清楚。@VPeric我明白了,谢谢!最清楚的答案是
x.replaceAll([[[(){},;!?%],”)
但如果做多次,速度会很慢。用
[[[(){},;!?%]
的模式编译正则表达式,然后执行
p.matcher(x).replaceAll(“”
。如果试图从代码中挤出最后一个机器周期,则可以创建一个65536元素的布尔数组c
Pattern p = Pattern.compile("[,.;!?(){}\\[\\]<>%]"); //store it somewhere so 
                                         //you wont need to compile it again
tmp = p.matcher(tmp).replaceAll("");
private static String processWord(String x) {
    return x.replaceAll("[][(){},.;!?<>%]", "");
}
private static final Pattern UNDESIRABLES = Pattern.compile("[][(){},.;!?<>%]");

private static String processWord(String x) {
    return UNDESIRABLES.matcher(x).replaceAll("");
}
private static final boolean[] CHARS_TO_KEEP = new boolean[];