티스토리 뷰

오랜만에 알고리즘 문제 풀던 중 문자열 내 특수문자 한 종류를 제거하기 위해 다음과 같은 코드를 실행했다.

str = str.replaceAll(c, ""); //c = "+"

java.util.regex.PatternSyntaxException: Dangling meta character 예외가 발생했다.

사실 replaceAll이라는 함수 내용을 정확히 보지 않고 이름만 보고 str 내의 모든 c 를 "" 으로 바꾸어주겠지 싶었다.

이름만 봐서는 그냥 replace(a, b)는 가장 첫 a 만 바꾸어주는거고 replaceAll(a, b)는 문자열 내의 모든 a를 바꾸어주는거 처럼 보였기 때문이다... (찾아보니 많이들 이렇게 착각한다고..)

 

replace() 와 replaceAll()은 모두 (String, String)으로 매개변수를 받지만 replaceAll()의 첫번째 매개변수는 regex이다.

따라서 c 안에 특수문자 하나가 있는 경우 이상한 정규표현식이기 때문에 이런 오류가 나는것이다.

 

java.util.regex.PatternSyntaxException: Dangling meta character ‘+’ near index 0

예외 로그를 해석해보면 "정규표현식 해석하려고 하는데 그냥 메타 문자 + 하나만 인덱스 0에 달랑 있잖아"라는 뜻이다.

메타문자는 정규 표현식에서 사용하는 특수문자 (특정 기능을 하기 위해 미리 지정해둔 문자)인데 위의 코드는 마치 수학에서 사용하는 특수문자 괄호를 '(' 하나만 쓰고 ')'로 닫지 않은 것과 비슷한 상황이기 때문에 PatternSyntaxException (정규표현식 구문 오류)가 발생한 것이다.

 

그럼 해결책은 무엇일까? 특정 문자열에 대한 치환을 하고 싶으면 replace()함수를 사용하고, 특수문자 제거 같은 상황은 그냥 깔끔하게 정규표현식 하나로 처리하는게 제일 좋은 것 같다.

 

str = str.replaceAll("[^a-zA-Z0-9]", "");
str = str.replaceAll("[-+^]*", "");

 

사실 그동안 정규표현식을 사용하면서 replaceAll() 사용한 적이 있음에도 이런 기초적인 실수를 했다는 것은 아직도 코드를 짜면서 내가 무슨 말을 써놓은건지 완전히 이해하지 못한 상태라는 것을 보여주는 것 같다. 별 생각 없이 넘긴 것들을 점검해보는 습관을 들이자. (근데 함수명은 좀 잘못 지은거 같다...) 

 

참고:

https://stackoverflow.com/questions/13791495/replace-all-with-in-java

 

Replace all "?" with "\\?" in Java

is it possible to replace all the questionmarks ("?") with "\?" ? Lets say I have a String, and I want to delete some parts of that String, one part with an URL in it. Like this: String longstri...

stackoverflow.com