在 java.lang.String
中,replace
方法采用一对 char 或一对 CharSequence
(其中 String 是一个子类,因此它很乐意采用一对 String)。 replace
方法将替换所有出现的 char 或 CharSequence
。另一方面,replaceFirst
和 replaceAll
的第一个 String
参数是正则表达式 (regex)。使用错误的函数可能会导致细微的错误。
问: java.lang.String
方法 replace()
和 replaceAll()
有什么区别,除了后者使用正则表达式。
答:只是正则表达式。他们都替换了所有:)
http://docs.oracle.com/javase/8/docs/api/java/lang/String.html
PS:
还有一个 replaceFirst()
(需要一个正则表达式)
CharSequence
是。 replace()
和 replaceAll()
都“与 CharSequence
一起工作”。这是因为 replaceAll()
将给定的 CharSequence
视为正则表达式,因此它会查找 regex 匹配,而 replace()
将给定的 CharSequence
视为纯搜索文本,因此它会查找 它的发生。
replace()
和 replaceAll()
都替换字符串中的所有匹配项。
例子
我总是找到有助于理解差异的示例。
代替()
如果您只想用另一个 char
替换一些 char
或用另一个 String
(实际上是 CharSequence
)替换一些 String
,请使用 replace()
。
示例 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
全部替换()
如果您想使用 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
也可以看看
文档
替换(char oldChar,char newChar)
replace(CharSequence 目标,CharSequence 替换)
replaceAll(字符串正则表达式,字符串替换)
replaceFirst(字符串正则表达式,字符串替换)
常用表达
教程
模式列表
replace()
方法被重载以接受原始 char
和 CharSequence
作为参数。
现在就性能而言,replace()
方法比 replaceAll()
快一点,因为后者首先编译正则表达式模式,然后在最终替换之前匹配,而前者只是匹配提供的参数并替换。
由于我们知道正则表达式模式匹配有点复杂,因此速度较慢,因此建议尽可能首选 replace()
而不是 replaceAll()
。
例如,对于您提到的简单替换,最好使用:
replace('.', '\\');
代替:
replaceAll("\\.", "\\\\");
注意:上述转换方法参数是系统相关的。
Pattern.compile(...)
内容/部分,似乎 replace
不太复杂定义/发送第一个参数。它不需要 "\"
。此外,replace
自 Java 1.5
起可用,replaceAll
自 1.4
起可用
replace() 和 replaceAll() 都接受两个参数,并用第二个子字符串(第二个参数)替换字符串中第一个子字符串(第一个参数)的所有出现。 replace() 接受一对 char 或 charsequence,replaceAll() 接受一对正则表达式。 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?"
replace
不调用 Pattern.compile(regex).matcher(this).replaceAll(replacement);
。它调用 Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
String replace(char oldChar, char newChar)
返回一个新字符串,该字符串是用 newChar 替换此字符串中所有出现的 oldChar 所产生的。
String replaceAll(String regex, String replacement
用给定的替换替换此字符串中与给定正则表达式匹配的每个子字符串。
举一个例子来说明两者如何在以下代码中工作:
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 替换空格。 String s 中的 \\s 与遇到的第一个 \ 一起转义并变为 \s。
Intellij Idea 足够聪明,可以通知您使用情况。如果您仔细查看下图,您会看到 Intellij idea 对 replace 和 replaceAll 用法的解释不同。
https://i.stack.imgur.com/ICXW7.png
我知道旧线程,但我对 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 );
String.replaceAll()
期望 regular expressions 不是文字参数,这就是为什么您会得到“不可预测”(实际上是非常可预测的)结果的原因。 String.replace()
以您想要的方式工作。
正如 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() 一起使用时。
从 Java 9 开始,replace 方法进行了一些优化。
在 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 开始。
https://i.stack.imgur.com/TMb7B.png
和 Stringlatin 实现。
https://i.stack.imgur.com/7RW94.png
哪个表现更好。
replace()
方法不使用正则表达式模式,而 replaceAll()
方法使用正则表达式模式。因此 replace()
的执行速度比 replaceAll()
快。
要添加到已选择的“最佳答案”(以及其他与 Suragch 一样好的答案),String.replace()
受到替换连续字符的限制(因此采用 CharSequence
)。但是,String.replaceAll()
不受仅替换连续字符的限制。只要您的正则表达式是以这种方式构造的,您就可以替换非连续字符。
此外(最重要且非常明显),replace()
只能替换文字值;而 replaceAll
可以替换 'like' 序列(不一定相同)。
replace 适用于 char 数据类型,但 replaceAll 适用于 String 数据类型,并且都将第一个参数的所有出现替换为第二个参数。
str.replaceAll(regex, repl)
的每次调用都与Pattern.compile(regex).matcher(str).replaceAll(repl)
相同。所以有很大的开销取决于它的使用量。String#replace(target, replacement)
做了同样的事情,只是它引用了字符串:Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
是否有某些原因为什么String#replace
会比String#replaceAll
快?它看起来不像,因为String#replace
只是执行额外的操作。replaceAll
的显式比较在哪里。答案更多关于replace