文字列replace()とreplaceAll()の違い


221

java.lang.String replace()replaceAll()メソッドの違いは何ですか(後で正規表現を使用する以外)のような単純な置換の場合、で置き換えます./ 、何か違いはありますか?

回答:


174

ではjava.lang.Stringreplaceメソッドは1組のcharまたは2組ののいずれかを取りますCharSequence(そのStringはサブクラスなので、1組のStringを喜んで受け取ります)。このreplaceメソッドは、出現するすべてのcharまたはを置き換えますCharSequence。一方、両方Stringの引数にreplaceFirstしてreplaceAll、正規表現(正規表現)です。間違った関数を使用すると、微妙なバグが発生する可能性があります。


30
さらに、Javaのドキュメントによると、への各呼び出しstr.replaceAll(regex, repl)はと同じPattern.compile(regex).matcher(str).replaceAll(repl)です。そのため、使用量によっては大きなオーバーヘッドがあります。
user845279 2012年

4
@ user845279それString#replace(target, replacement)が文字列を引用していることを除いて同じことをするので、あなたが言うのは興味深いです:よりも高速になるPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));理由はありますか?追加の操作を実行するだけなので、そのようには見えません。String#replaceString#replaceAllString#replace
2018

1
興味があるだけ、この答えにどこに対する明示的な比較ですreplaceAll。答えはもっと詳しくreplace
マヌエルジョーダン

これは、replaceAll()が正規表現一致のためにコストがかかることを意味しますか?
不思議

97

Q:java.lang.Stringメソッドreplace()との違いは何ですか?replaceAll()それ以外は、正規表現を使用します。

A:正規表現だけです。彼らは両方ともすべてを置き換えます :)

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

PS:

replaceFirst()(正規表現が必要)もあります。


1
それは単なる正規表現であることを明確にするためのThx。replaceAll()の代わりにreplaceWithRegex()と名前を付けたらどうだろう
HopeKing

明確化: replaceAll()は正規表現で動作し、replace()はCharSequenceで動作します
ジョニーファイブ

2
@JohnnyFiveそれはそれをより混乱させます。正規表現は型ではないCharSequenceです。両方replace()replaceAll()「で働くCharSequence」。これreplaceAll()は、指定さCharSequenceれたものを正規表現と見なして正規表現の一致を探す一方でreplace()、指定さCharSequenceれたものをプレーン検索テキストと見なして、その出現を探します。
SantiBailors

43

両方とも、文字列内のすべての出現箇所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()

正規表現パターン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 String docs :: public String replace(CharSequence target、CharSequence replacement){return Pattern.compile(target.toString()、Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement (replacement.toString())); }
Prateek 2013

@Prateek:jdk8の後、String :: replaceはパターンを使用しなくなりました:hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/…、jdk11と同じです。
フランク

同意、でJava 8は、実質的に両方の方法があり、ほとんどの両方が表示されるため、同じPattern.compile(...)彼らの実装でコンテンツ/一部を、と思われるreplace最初の引数を送る/定義する方法についてそれほど複雑です。必要ありません"\"。さらに、replaceJavaのため、利用可能である1.5replaceAll以来1.4
マヌエル・ジョーダン

3
String replace(char oldChar, char newChar)

この文字列内のすべてのoldCharをnewCharで置き換えた結果の新しい文字列を返します。

String replaceAll(String regex, String replacement

指定された正規表現に一致するこの文字列の各部分文字列を、指定された置換で置き換えます。


3
  1. replace()とreplaceAll()はどちらも2つの引数を受け入れ、文字列内の最初の部分文字列(最初の引数)のすべての出現箇所を2番目の部分文字列(2番目の引数)に置き換えます。
  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 2016

replaceAll()は正規表現のペアを受け入れます。なぜ検索文字列と置換文字列の両方が正規表現になるのでしょうか。オカレンスは何に置き換えられますか?正規表現を使って?もちろん、最初の引数だけが正規表現(検索文字列)です。2番目は正規表現(置換文字列)ではありません。
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は初めての人で、奇妙なものの1つを発見しました。使用しました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()思い通りに動作します。
Nadar 2016年

Javaから予期しない結果が出るときの経験則として、それを回避するための新しい関数を設計するのではなく、それらの結果は完全に適切であり、使用しているJava機能を誤解していると想定することをお勧めします。
SantiBailors

0

すでに選択されている「ベストアンサー」(およびSuragchのものと同じくらい優れている他のもの)に追加するには、String.replace()連続している文字を置き換える(したがってを使用するCharSequence)ことによって制約されます。ただし、String.replaceAll()連続する文字のみを置き換えることによる制約はありません。正規表現がこのように構成されている限り、非順次文字を置き換えることができます。

また、(最も重要で痛々しいほど明白な)replace()リテラル値のみを置き換えることができます。一方replaceAll、「類似」シーケンス(必ずしも同一である必要はありません)を置き換えることができます。


-1

replace()メソッドは正規表現パターンを使用しませんが、replaceAll()メソッドは正規表現パターンを使用します。したがってreplace()、よりも高速に実行されますreplaceAll()


3
それは真実ではない。置換のソースを見ると、パターンとマッチャー(つまり正規表現)も使用されていることがわかります
xtrakBandit

-5

replaceはcharデータ型で機能しますが、replaceAllはStringデータ型で機能し、両方とも最初の引数のすべての出現を2番目の引数で置き換えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.