Java

[Java] String클래스 메서드 replace()와 replaceAll() 차이점

haehyun 2021. 10. 7. 22:31

replace()와 replaceAll()

문자열 타입을 나타내는 String 클래스에는 replace()와 replaceAll() 메서드가 존재하는데 일반 문자열 리터널로 해당 메서드를 실행하면 실행결과에 차이가 없다.

package ch9;

public class StringEx1 {
	public static void main(String[] args) {
		//replace()
		String s = "Hello Hello";
		String s1 = s.replace("ll", "LL");
		
		System.out.println("s:  "+s);
		System.out.println("s1: "+s1);
		
		//replaceAll()
		String s2 = "Hello Hello";
		String s3 = s2.replaceAll("ll", "LL");
		
		System.out.println("s2: "+s2);
		System.out.println("s3: "+s3);
	}
}
s:  Hello Hello
s1: HeLLo HeLLo
s2: Hello Hello
s3: HeLLo HeLLo

위의 실행결과에서 볼 수 있듯, 두 메서드 모두 특정 문자열이 새로운 문자열로 대체된 결과(String)를 반환한다.
왜 같은 기능을 하는 메서드가 두개나 있을까? 정확히 두 메서드가 어떤 기능을 하는지 살펴보자.

 

메서드 설명
String replace(CharSequence old, CharSequence new) 문자열 중의 문자열(old)을 새로운 문자열(new)로 모두 바꾼 문자열을 반환한다.
String replaceAll(String regex, String replacement) 문자열 중에서 지정된 문자열(regex)과 일치하는 것을 새로운 문자열(replacement)로 모두 변경한다.
  • CharSequence : JDK1.4에 추가된 인터페이스. String, StringBuffer 등 클래스에서 구현한다.
    *메서드 선언부 매개변수가 인터페이스 타입으로 기재되어있을 경우, 해당 인터페이스를 구현(inplement)한 클래스의 인스턴스들을 매개변수로 받을 수 있다.
  • regex : 정규식, 특정 문자열을 나타내는 규칙
  • replacement : 대체어

선언부의 매개변수명을 통해 두 메서드의 차이를 한눈에 알아볼 수 있다.
replace메서드는 매개변수명이 old, new로 되어있는 한편, replaceAll()메서드는 매개변수명이 regex, replacement로 되어 있다. replace()는 특정 문자열을 새로운 문자열로 대체하기 위한 메서드이며, replaceAll은 정규식에 일치하는 문자열들을 전부 다른 문자열로 대체하기 위한 메서드인 것이다.

 

정규식

여기서 정규식(regular expression = regex)이란,
정규 표현식의 준말로 문자열에서 특정한 형태나 규칙을 가진 문자열을 찾아내기 위해 나타내는 패턴이다.
ex) 회원가입 시 고객이 입력한 이메일이 xxx@naver.com형태인지 체크, 아이디가 영문+숫자 조합인지 체크할 때 사용

정규식은 . [] [^] ^ $ () \n * {} 등의 특수문자와 영문, 숫자 등의 조합으로 구성할 수 있다. (정규식에 관한 내용은 너무 많아서 나중에 자세히 다루기로..) 프로그래밍에서 자주 사용되는 기본 정규식은 아래와 같다.

영어 [a-zA-z]
숫자 [0-9]
영어+숫자 [a-zA-Z0-9]
이메일 [a-zA-Z0-9]+@[a-zA-Z0-9]+
전화번호 \d{2, 3}-\d{3, 4}-\d{4}
주민등록번호 \d{6}\-[1-4]\d{6}

 

replace()와 replaceAll() + 정규식

처음 소스코드에 정규식을 추가하여 새롭게 테스트 해보자.
아래 소스코드는 각각 replace()와 replaceAll()을 사용하여 문자열에 포함된 영문자를 공백으로 대체한다.

package ch9;

public class StringEx1 {
	public static void main(String[] args) {
		//replace()
		String s = "helloworld에 오신걸 welcome합니다~";
		String s1 = s.replace("helloworld", "").replace("welcome", "");
		
		System.out.println("s:  "+s);
		System.out.println("s1: "+s1);
		System.out.println();
		
		//replaceAll()
		String s2 = "helloworld에 오신걸 welcome합니다~";
		String s3 = s2.replaceAll("[a-z]", "");
		
		System.out.println("s2: "+s2);
		System.out.println("s3: "+s3);
	}
}
s:  helloworld에 오신걸 welcome합니다~
s1: 에 오신걸 합니다~

s2: helloworld에 오신걸 welcome합니다~
s3: 에 오신걸 합니다~
  • String s1 = s.replace("helloworld", "").replace("welcome", "");
    "helloworld에 오신걸 welcome합니다~" 문자열에서 "helloworld"문자열을 공백으로 대체,
    그렇게 대체된 결과 문자열에서 다시 "welcome"문자열을 공백으로 대체
  • String s3 = s2.replaceAll("[a-z]", "");
    "helloworld에 오신걸 welcome합니다~" 문자열에서 정규식에 일치하는 문자열을 공백으로 대체.
    [a-z]는 소문자 a~z를 나타내므로, 문자열에서 소문자를 전부 공백으로 대체.

두 방법 모두 실행결과는 같지만, 위 조건에서 replace()를 이용한 방법은 프로그래밍적이지 못하다.
replace()는 특정 문자열을 대체할 때 (ex: 제품명에서 "텔레비전"을 전부 "TV"로 변경),
replaceAll()은 특정 패턴의 문자열을 대체할 때 (ex: 제품명에서 숫자를 전부 제거(=공백으로 대치)) 적합하다.

요약

replace() : 문자열 대치
replaceAll() : 문자열 대치 + 정규식 적용 가능