String replace ()와 replaceAll ()의 차이점


221

나중에 정규식을 사용하는 것 외에 java.lang.String replace()replaceAll()메소드 의 차이점은 무엇입니까 ? 교체 같은 간단한 대체의 경우 ./ 어떤 차이가?

답변:


174

에서 java.lang.Stringreplace방법은 두 문자의 한 쌍 또는 한 쌍의 소요 CharSequence(이 행복하게 문자열의 한 쌍을거야, 그래서 문자열 서브 클래스로되어있는) '들. 이 replace메소드는 모든 문자 또는를 대체합니다 CharSequence. 반면에, 모두 String인수 replaceFirst하고 replaceAll정규 표현식 (정규식을)입니다. 잘못된 기능을 사용하면 미묘한 버그가 발생할 수 있습니다.


30
또한 Java 문서에 따르면에 대한 각 호출은와 str.replaceAll(regex, repl)동일합니다 Pattern.compile(regex).matcher(str).replaceAll(repl). 따라서 사용되는 양에 따라 큰 오버 헤드가 있습니다.
user845279 2016 년

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추가 작업을 수행 하기 때문에 그렇게 보이지 않습니다 .
Horsey

1
이 답변에서에 대한 명시 적 비교가 어디에 있는지 궁금 replaceAll합니다. 이에 대한 자세한 내용은replace
Manuel Jordan

이것은 정규식 일치로 인해 replaceAll ()이 더 비싸다는 것을 의미합니까?
궁금해

97

Q : 나중에 정규식을 사용하는 것 이외 의 java.lang.String방법 replace()과 의 차이점은 무엇입니까?replaceAll()

A : 정규식입니다. 둘 다 모두 대체합니다 :)

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

추신:

또한 replaceFirst()(정규식이 필요합니다)


1
그것이 정규 표현식이라는 것을 명확히하기 위해 Thx. 어떻게 그들이 replaceAll () 대신 replaceWithRegex ()라는 이름을 붙 였는지
HopeKing

설명 : replaceAll ()은 정규식과 작동하고 replace ()는 CharSequence와 작동
Johnny Five

2
@JohnnyFive 더 혼란 스럽습니다. 정규 표현식은 유형이 아닙니다 CharSequence. 모두 replace()replaceAll()"와 작업 CharSequence". 그것은 그건 replaceAll()주어진 고려 CharSequence가 찾습니다 있도록 정규 표현식으로 정규식 일치 하면서, replace()주어진 고려 CharSequence가 찾습니다 있도록 일반 검색 텍스트로 발생 그것의.
SantiBailors

43

모두 replace()replaceAll()String의 모든 항목을 대체합니다.

나는 항상 차이점을 이해하는 데 도움이되는 예를 찾습니다.

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()메소드는 기본 요소 charCharSequence인수 를 모두 인수로 오버로드됩니다 .

이제 성능과 관련하여 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

@Prateek : jdk8 이후, String :: replace는 더 이상 Pattern을 사용하지 않습니다 : hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/… , jdk11과 동일합니다.
Franck

동의합니다 .Java 8에서 실제로 두 가지 방법은 거의 동일합니다. 두 가지 Pattern.compile(...)구현에서 내용 / 부분이 나타나기 replace때문에 첫 번째 인수를 정의 / 전송하는 방법에 대해서는 덜 복잡합니다. 필요하지 않습니다 "\". 또한 replace자바부터 사용할 수 있습니다 1.5replaceAll이후1.4
마누엘 요르단

3
String replace(char oldChar, char newChar)

이 문자열에서 모든 oldChar 발생을 newChar로 바꾼 결과로 새 문자열을 리턴합니다.

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

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()원하는 방식으로 작동합니다.
Nadar

우리가 Java에서 예기치 않은 결과를 얻을 때이를 해결하기위한 새로운 기능을 설계하는 대신 경험할 수있는 결과로서, 그 결과가 적절하지 않고 사용중인 Java 기능을 잘못 이해하고 있다고 가정하는 것이 좋습니다.
SantiBailors

0

이미 선택된 "Best Answer"(및 Suragch와 같은 다른 것)에 추가하려면 String.replace()순차적 인 문자를 대체하여 제한됩니다 (따라서 CharSequence). 그러나 String.replaceAll()순차 문자 만 대체하여 제한되지는 않습니다. 정규식이 그런 식으로 구성되는 한 비 순차적 문자를 대체 할 수 있습니다.

또한 (가장 중요하고 고통스럽게도 분명) replace()리터럴 값만 대체 할 수 있습니다. 반면 replaceAll'유사'시퀀스를 대체 할 수 있습니다 (반드시 동일 할 필요는 없음).


-1

replace()메서드는 정규식 패턴을 사용하지 않지만 replaceAll()메서드는 정규식 패턴을 사용합니다. 그래서 replace()보다 더 빨리 수행합니다 replaceAll().


3
그건 사실이 아니야. 교체 소스를 살펴보면 패턴 및 매처 (예 : 정규식)도 사용
했음을 알 수 있습니다.

-5

replace는 char 데이터 형식에서 작동하지만 replaceAll은 String 데이터 형식에서 작동하며 두 번째 인수는 첫 번째 인수의 모든 항목을 두 번째 인수로 바꿉니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.