캠핑과 개발

JAVA replaceAll +1

프로젝트 완료후 운영과정에서 의도하지 않은 오류가 발생했다.

문제가 된 부분은 메일 발송중에 에러가 발생했는데 흔히 메일 템플릿을 만들어 놓고 사용자명이라던지 비빌번호는 특정한 문구로 넣고 메일 발송 과정에서 해당 특정 문구를 해당 사용자의 이름과 비밀번호로 replace하여 메일을 발송하게 된다.


예를 들어 메일 템플릿에는 다음과 같은 문구가 있다.

이름 : #NAME#

비밀번호 : #PASSWORD#


해당 부분은 사용자가 메일을 받을 시점엔 다음과 같이 변경이 될것이다.

이름 : 홍길동

비밀번호 : testpassword


물론 비밀번호를 이렇게까지 표출 하는 곳은 없겠지만 예를 들어 설명한 부분이다.


일반적으로 템블릿의 특정 부분을 변경하기 위해서는 replaceAll()를 사용하게 되는데 여기에서 문제가 발생했다.

다들 신경쓰는 부분은 replaceAll(String arg1, String arg2) 메서드의 첫번째 인자를 신경쓰게 된다.

첫번째 인자는 정규표현식을 넣어야 하는데 정규표현식에서 특수문자를 문자열로 인식하기 위해서 [], \\를 감싸거나 앞에 붙여준다.


하지만 이번 문제는 2번째 인자에서 발생을 했는데 넘어가는 값은 "$0testword"와 같은 문자열이였다.

해당 문자는 소스상에서 다음과 같은 형태로 구현될것이다.


  1. String template= "비밀번호 : #PASSWORD#";
  2. String password = "$0testword";
  3.  
  4. template = template.replaceAll("#PASSWORD#", password );
  5. System.out.println(template);


정상적으로 문자열이 변경이 될것이라 생각했는데 에러가 발생을 했다.


간단하게 말하면 문제에 원인은 변경될 문자열에 "$"이 포함되어 있기 때문이다. 그리고 \\이 들어갈 경우도 의도하지 않은 결과가 발생할 수 있다.

java replaceAll 소스를 보게되면 "$", "//"일 경우 다른 처리를 하게 되므로 해당 부분을 참고하기 바란다.


이를 해결하기 위해서는 $ --> \\$로 변경하면 해결이 된다.

  1. String template= "비밀번호 : #PASSWORD#";
  2. String password = "\\$0testword";
  3.  
  4. template = template.replaceAll("#PASSWORD#", password );
  5. System.out.println(template);



replaceAll 사용시 특수문자를 치환하기 위해서는 [], \\를 쓰는데 다음과 같이 구별하여 쓴다.

[]를 사용하는 특수문자    ==> *, +, $, |, ? ==> [*]

\\를 사용하는 특수문자 ==> (, ), {, }, [, ] ==> \\(

- 를 사용하기 위해서는 \ 한번 붙여준다.

\를 사용하기 위해서는 \\를 사용한다.