안녕하세요. 이번 시간에는 java string에 있는 trim 함수에 대해 알아봅시다. trim은 보통 문자열의 앞과 뒤에 붙어 있는 공백을 제거하기 위해서 쓰는 경우가 많습니다. 공백, 아니면 tab을 제거할 때요. 코딩 테스트에서는 이 정도에서 해결을 볼 수 있는 경우가 대다수입니다. 여기까지는 별 문제 없어 보입니다. 그런데, 저는 이 글을 상세 분석에 쓰고 있습니다. 이렇게 간단한 메서드를 왜 상세 분석에 쓸까요? 질문 하나 드리겠습니다. trim은 문자열의 맨 앞과, 맨 뒤에 붙은 모든 white space를 제거할까요?

 


 테스트 데이터를 만들어 보겠습니다. 3개의 String이 들어가 있는데요. 위에 2개는 white space가 공백과 new line, tab으로만 이루어져 있어요. 문제는 3번째 string인데요. 겉 보기에는 왼쪽에도 공백, 오른쪽에도 공백이 있는 거 같습니다.

 

 

 그러니, 3번째 문자열에 대해서 trim을 한 결과는 "abcde"가 나와야 할 겁니다. 정말 그렇게 나왔는지 보겠습니다.

 

 

 앞 뒤 공백이 제거되지 않았습니다. 이게 어떻게 된 일일까요? 우리가 알고 있는 공백 문자는 space, tab, 개행 정도밖에 없었는데요. 더 있나요? 왜 이렇게 되었는지 파악하기 위해서, trim을 한 문자열의 codePoint를 찍어보도록 하겠습니다.

 


 String에서 charAt(i)를 하면 i번째 index에 있는 문자열을 얻어옵니다.

 

 예를 들어 string에 space, 'a', tab 순서대로 있었다고 해 보겠습니다. 이 string에서 charAt(0)을 하면 SPACE 문자를 얻어옵니다.

 

 

 그런데, 이것을 int로 강제 형변환을 하면 32를 얻어오게 됩니다.

 

 10번째 줄부터 11번째 줄에 있는 for loop는 String에 있는 문자들의 codePoint를 출력합니다. 당연하게도, surrogate로 나누어 지는 (이모지 같은) 문자들이 아니라고 가정해 보겠습니다. 그러면 하나의 값은 하나의 문자에 대응하게 됩니다.

 

 

 보니까, 12288이 눈에 들어오네요. 이게 또 다른 공백의 code 값일 수도 있겠네요.

 

 

 실제로 12288의 HEX 값은 3000인데요. 이 문서에 있는 white space에 포함되는 값임을 알 수 있어요. 즉 HEX 값이 3000인 화이트 문자는 걸러지지 않았다는 의미가 됩니다. 왜 그럴까요?

 


 이는, trim 메서드의 내부를 보시면 쉽게 알 수 있습니다.

 

 val은 원본일 겁니다.

 

 그리고 val[st]가 공백 보다 작거나 같은 경우에 st는 증가시키고 len은 감소시키는데요. st와 len은 나중에 substring을 리턴할 때 쓰이는 변수입니다. 즉, 공백보다 codePoint 값이 큰 경우에는, 처리를 하지 않는다는 것입니다. 어떻게 해결해야 할까요?

 

 

 Character 클래스에는 isWhiteSpace 메서드가 있습니다. codePoint를 넣으면, 해당 문자가 WhiteSpace인지 확인해 주는데요. 이 메서드를 이용해서 걸러내 주시면 됩니다.

 

 

 실행 결과는 위와 같습니다.