字符串replace()和replaceAll()之间的区别


221

除了以后使用regex之外,java.lang.String replace()replaceAll()方法之间有什么区别?对于简单的替代喜欢,更换./ ,有什么不同?

Answers:


174

在中java.lang.String,该replace方法可以采用一对char或一对CharSequence(其中String是子类,因此很高兴采用一对String)。该replace方法将替换所有出现的char或CharSequence。在另一方面,这两个String参数replaceFirstreplaceAll正则表达式(正则表达式)。使用错误的功能可能导致细微的错误。


30
此外,根据Java文档,对的每次调用str.replaceAll(regex, repl)均与相同Pattern.compile(regex).matcher(str).replaceAll(repl)。因此,根据使用量的不同,会有很大的开销。
user845279

4
@ user845279有趣的是,您会说String#replace(target, replacement)同样的事情,除了它引用了字符串:Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));是否有某些原因String#replace会导致比更快String#replaceAll?由于String#replace只执行其他操作,因此看起来并不理想。
霍西

1
很好奇,在此答案中与的显式比较在哪里replaceAll。答案更多关于replace
Manuel Jordan

这意味着replacereg()由于正则表达式匹配而更加昂贵吗?
想知道

97

问:和的java.lang.String方法有什么区别,除了以后使用正则表达式。replace()replaceAll()

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

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

PS:

还有一个replaceFirst()(需要正则表达式)


1
感谢您澄清这只是正则表达式。我希望他们如何将其命名为replaceWithRegex()而不是replaceAll()
HopeKing

澄清: replaceAll()使用正则表达式,replace()使用CharSequence
Johnny,2005年5

2
@JohnnyFive这使它更加混乱。正则表达式不是类型,CharSequence而是。两者replace()replaceAll()“一起工作CharSequence”。这是replaceAll()考虑给定CharSequence为正则表达式,所以它看起来为正则表达式匹配,同时replace()考虑给予CharSequence以纯文本的搜索,所以它看起来对出现的吧。
SantiBailors

43

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

例子

我总是会找到一些有助于理解差异的示例。

replace()

使用replace(),如果你只是想更换一些char与另一个char或一些String与另一个String(实际上CharSequence)。

例子1

替换字符出现的所有xo

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

替换字符串中出现的所有fishsheep

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()

使用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

也可以看看

文献资料

常用表达


34

replace()方法被重载以接受原始char和a CharSequence作为参数。

现在,就性能而言,该replace()方法要快一些,replaceAll()因为后者首先编译正则表达式模式,然后在最终替换之前进行匹配,而前者只是匹配提供的参数并进行替换。

因为我们知道正则表达式模式匹配是一个稍微复杂一些,因此速度较慢,则宁愿replace()replaceAll()建议只要有可能。

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

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

代替:

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

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


6
甚至替换也一样。从java字符串文档:: 公共字符串替换(CharSequence目标,CharSequence替换){返回Pattern.compile(target.toString(),Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement (replacement.toString())); }
Prateek

@Prateek:在jdk8之后,String :: replace不再使用Pattern:hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/…,与jdk11中相同。
法兰克

同意,在Java 8中,实际上这两种方法几乎相同,因为这两种方法都Pattern.compile(...)在其实现中出现了内容/部分,replace关于如何定义/发送第一个参数似乎并不那么复杂。它不需要"\"。此外replace可从Java 1.5replaceAll1.4
曼努埃尔·乔丹

3
String replace(char oldChar, char newChar)

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

String replaceAll(String regex, String replacement

用给定的替换项替换该字符串中与给定的正则表达式匹配的每个子字符串。


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

    Pattern.compile(regex).matcher(this).replaceAll(replacement);

现在的问题是何时使用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?"

4
它们不是完全相同的实现。replace不打电话Pattern.compile(regex).matcher(this).replaceAll(replacement);。它呼吁Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
ChiefTwoPencils's

replaceAll()接受一对正则表达式为什么搜索字符串和替换字符串都为正则表达式?出现的情况将被替换为什么?使用正则表达式?当然,只有第一个参数是正则表达式(搜索字符串)。第二个不是正则表达式(替换字符串)。
SantiBailors

1

就像在wickeD的答案中提到的那样,使用replaceAll替换字符串在replace和replaceAll之间的处理方式有所不同。我期望a [3]和a [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()一起使用时。


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 );

1
String.replaceAll()期望正则表达式而不是文字参数,这就是为什么您得到“不可预测的”(实际上是非常可预测的)结果的原因。String.replace()以您想要的方式工作。
纳达尔

根据经验,当我们从Java中获得意想不到的结果时,与其设计一个新函数来解决这个问题,不如假定这些结果是正确的,并且我们误解了所使用的Java功能,这是更好的选择。
SantiBailors

0

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

同样(最重要和最痛苦的是)replace()只能替换文字值;而replaceAll可以替换“相似”序列(不一定相同)。


-1

replace()方法不使用正则表达式模式,而replaceAll()方法使用正则表达式模式。因此replace()执行速度比快replaceAll()


3
这不是真的。如果您查看替换的来源,您会发现它也使用了Pattern和Matcher(即regex)
xtrakBandit 2015年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.