String replace()和replaceAll()之间的区别

时间:2012-05-31 05:24:58

标签: java string replace

java.lang.String的replace()replaceAll()方法之间有什么区别, 除了以后使用正则表达式?对于简单的替换,例如,将.替换为/, 有什么不同吗?

13 个答案:

答案 0 :(得分:149)

java.lang.String中,replace方法需要一对char或一对CharSequence(其中String是子类,所以它很乐意带一对String的)。 replace方法将替换所有出现的char或CharSequence。另一方面,StringreplaceFirst的{​​{1}}个参数都是正则表达式(正则表达式)。使用错误的功能可能会导致细微的错误。

答案 1 :(得分:76)

问: java.lang.String方法replace()replaceAll()之间有什么区别,而后者使用正则表达式除外。

A:只是正则表达式。他们都替换所有:)

http://docs.oracle.com/javase/6/docs/api/java/lang/String.html

PS:

还有replaceFirst()(采用正则表达式)

答案 2 :(得分:30)

重载replace()方法以接受原始charCharSequence作为参数。

就性能而言,replace()方法比replaceAll()快一点,因为后者首先编译正则表达式模式,然后在最终替换之前匹配,而前者只是匹配提供论证并替换。

由于我们知道正则表达式模式匹配有点复杂,因此速度较慢,因此建议尽可能优先replace()而不是replaceAll()

例如,对于您提到的简单替换,最好使用:

replace('.', '\\');

而不是:

replaceAll("\\.", "\\\\");

注意:上述转换方法参数与系统有关。

答案 3 :(得分:22)

replace()replaceAll()都会替换字符串中的所有匹配项。

实施例

我总是找到有助于理解差异的例子。

replace()

如果您只想将某些replace()替换为另一个char,或将某些char替换为另一个String(实际为String),请使用CharSequence

示例1

将所有出现的字符x替换为o

String myString = "__x___x___x_x____xx_";

char oldChar = 'x';
char newChar = 'o';

String newString = myString.replace(oldChar, newChar);
// __o___o___o_o____oo_

示例2

将所有出现的字符串fish替换为sheep

String myString = "one fish, two fish, three fish";

String target = "fish";
String replacement = "sheep";

String newString = myString.replace(target, replacement);
// one sheep, two sheep, three sheep

replaceAll()

如果您想使用regular expression pattern,请使用replaceAll()

示例3

x替换任何数字。

String myString = "__1_6____3__6_345____0";

String regex = "\\d";
String replacement = "x";

String newString = myString.replaceAll(regex, replacement); 
// __x_x____x__x_xxx____x

示例4

删除所有空格。

String myString = "   Horse         Cow\n\n   \r Camel \t\t Sheep \n Goat        ";

String regex = "\\s";
String replacement = "";

String newString = myString.replaceAll(regex, replacement); 
// HorseCowCamelSheepGoat

另见

文档

正则表达式

答案 4 :(得分:3)

String replace(char oldChar, char newChar)

返回一个新字符串,该字符串是用newChar替换此字符串中所有出现的oldChar而生成的。

String replaceAll(String regex, String replacement

将此字符串中与给定正则表达式匹配的每个子字符串替换为给定的替换。

答案 5 :(得分:3)

  1. replace()和replaceAll()接受两个参数,并用第二个子字符串(第二个参数)替换字符串中第一个子字符串(第一个参数)的所有匹配项。
  2. replace()接受一对char或charsequence,replaceAll()接受一对正则表达式。
  3. 并非replace()的工作速度比replaceAll()更快,因为两者在其实现中使用相同的代码

    Pattern.compile(正则表达式).matcher(本).replaceAll(替换);

  4. 现在的问题是何时使用replace以及何时使用replaceAll()。 如果要将子字符串替换为另一个子字符串而不管其在字符串中的出现位置,请使用replace()。但是如果你有一些特殊的偏好或条件,比如只替换字符串开头或结尾的那些子串,请使用replaceAll()。以下是一些证明我的观点的例子:

    String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
    String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
    String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
    

答案 6 :(得分:1)

在wickeD的回答中提到,使用replaceAll替换字符串在replace和replaceAll之间的处理方式不同。我期望[3]和[4]具有相同的值,但它们是不同的。

public static void main(String[] args) {
    String[] a = new String[5];
    a[0] = "\\";
    a[1] = "X";
    a[2] = a[0] + a[1];
    a[3] = a[1].replaceAll("X", a[0] + "X");
    a[4] = a[1].replace("X", a[0] + "X");

    for (String s : a) {
        System.out.println(s + "\t" + s.length());
    }
}

这个输出是:

\   1
X   1
\X  2
X   1
\X  2

这与perl不同,其中替换不需要额外的转义级别:

#!/bin/perl
$esc = "\\";
$s = "X";

$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";

打印 \ X 2

当尝试使用java.sql.DatabaseMetaData.getSearchStringEscape()返回的值和replaceAll()时,这可能会非常麻烦。

答案 7 :(得分:0)

我知道的旧线程,但我对Java有点新鲜,并发现其中一个奇怪的事情。我使用了String.replaceAll()但得到了不可预知的结果。

像这样的东西弄乱了字符串:

sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");

所以我设计了这个函数来解决这个奇怪的问题:

//String.replaceAll does not work OK, that's why this function is here
public String strReplace( String s1, String s2, String s ) 
{
    if((( s == null ) || (s.length() == 0 )) || (( s1 == null ) || (s1.length() == 0 )))
     { return s; }

   while( (s != null) && (s.indexOf( s1 ) >= 0) )
    { s = s.replace( s1, s2 ); }
  return s;
}

这使你能够做到:

sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );

答案 8 :(得分:0)

要添加到已经选择的“最佳答案”(以及与Suragch一样好的其他答案)中,String.replace()受限制于替换连续字符(因此取CharSequence)。但是,String.replaceAll()不受仅替换连续字符的限制。只要正则表达式是用这种方式构造的,就可以替换非顺序字符。

(最重要也是最痛苦的是)replace()只能替换文字值;而replaceAll可以替换'like'序列(不一定相同)。

答案 9 :(得分:0)

从Java 9开始,替换方法进行了一些优化。

在Java 8中,它使用正则表达式。

public String replace(CharSequence target, CharSequence replacement) {
    return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
            this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}

从Java 9开始。

enter image description here

和Stringlatin实现。

enter image description here

哪个表现更好。

https://medium.com/madhash/composite-pattern-in-a-nutshell-ad1bf78479cc?source=post_internal_links---------2------------------

答案 10 :(得分:0)

通过一个例子来说明两者如何在下面的代码中工作:

public static void main(String[] args)
{
    String s = "My\\s aaab\\s is\\s aaab\\s name";
    String s1 = s.replace("\\s", "c");
    System.out.println(s1);
    String s2 = s.replaceAll("\\s", "c");
    System.out.println(s2);
}

输出:

Myc aaabc isc aaabc name
My\scaaab\scis\scaaab\scname

说明

s.replace 用 c 替换“\\s”字符序列。因此,第一行的输出。 s.replaceAll 将 \\s 视为正则表达式(相当于空格)并用 c 替换空格。字符串 s 中的 \\s 在遇到第一个 \ 时被转义并变为 \s。

Intellij Idea 足够聪明,可以通知您使用情况。如果您仔细查看下图,您会发现 Intellij 对 replace 和 replaceAll 用法的解释存在差异。

enter image description here

答案 11 :(得分:-1)

java.lang.NullPointerException方法不使用正则表达式模式,而replace()方法使用正则表达式模式。因此replaceAll()的执行速度高于replace()

答案 12 :(得分:-5)

替换有关char数据类型的工作,但replaceAll对String数据类型有效,并且都用第二个参数替换所有出现的第一个参数。