본문 바로가기
320x100
320x100

Whitespace Characters는 공백문자

그리고 이 WhiteSpace Character의 종류에는
1. 가로 크기를 차지하는 공백 문자(눈에 보임)
2. 세로 크기를 차지하는 공백 문자(눈에 보임)
3. 1 또는 2지만 눈에 보이지 않는 공백 문자가 있다

특히 3번의 경우는 일부러 사용하는 경우도 있고(화면에 보여줄 때), 일부러 제거하는 경우도 있다(서버에서 받을 때)

아니 3번같은게 어디 있어~? 라고 말씀하시는 분들은 아래에 더블클릭으로 보라돌이 뚜비 나나 뽀를 선택해보자
NORMAL의 경우는 전체가 블록으로 지정되고, SPACE의 경우는 공백마다 블록 지정, ZERO_WIDTH_SPACE의 경우에는 눈에는 NORMAL이랑 비슷하지만 [보라돌이]를 누르면 보라돌이만 선택되고 [뚜비]쪽을 누르면 뚜비만 선택되는 모습을 볼 수 있다
이게 바로 크기를 차지하지 않는 공백이다
Zero Width SPace, 줄여서 ZWSP라고 부른다
그럼 이 ZWSP를 언제 사용할까?
이 ZWSP는 중국어나 일본어와 같이 띄어쓰기가 없는 문자에 대해서 특히 유용하다
또는 하나의 단어에서 일정 부분만 선택하거나 CSS에 의해 개행하고 싶을때 ZWSP를 사용하면 처리가 가능하다
하지만 API호출로 백단에서 DB로 데이터를 저장하는데, 눈에 보이거나 보이지 않는 공백까지 같이 저장이 된다면?
개인적으로는 아무리 화면단에서 UX(User Experience)를 위해 ZWSP를 사용하는게 조금 유용할지라도, 백단과 프론트 협의하에 사용하지 않는 편이 좋을것같긴한데.. 이미 사용하고 있는 분들을 위해서 눈에 보이는 공백 또는 보이지 않는 공백을 없애는 코드를 테스트해보고 공유해보려고 한다

// NORMAL
보라돌이뚜비나나뽀

// SPACE
보라돌이 뚜비 나나 뽀

// ZERO_WIDTH_SPACE
보라돌이​뚜비​나나​뽀

그리고 WhiteSpace는 위키백과 기준으로 Width box를 보면 크기를 얼만큼 차지하는지 알 수 있다
https://en.wikipedia.org/wiki/Whitespace_character

여기에서 프로그래밍 영어라고 해야하나..음 우리가 보통 Tab/탭 이라고 말하는 영어의 풀네임은 TABULATION이었다!
정확히는 Tabulator Key이다

나는 위키백과의 내용 대신
https://jkorpela.fi/chars/spaces.html
https://qwerty.dev/whitespace/
두 페이지의 내용들로 테스트를 진행해보았다

여기에 추가로 BRAILLE SPACE와 CAUCASIAN_ASTRONAUT를 더했다
준비된 사수로부터 코드 테스트 준비 완료!

String SPACE = " ";                                    //            // U+0020
String NO_BREAK_SPACE = " ";                        //         // U+00A0
String OGHAM_SPACE_MARK = " ";                         //             // U+1680
String MONGOLIAN_VOWEL_SEPARATOR = "\u180E";           // ᠎           // U+180E
String EN_QUAD = " ";                               //         // U+2000
String EM_QUAD = " ";                               //         // U+2001
String EN_SPACE = " ";                              //         // U+2002
String EM_SPACE = " ";                              //         // U+2003
String THREE_PER_EM_SPACE = " ";                   //        // U+2004
String FOUR_PER_EM_SPACE = " ";                    //        // U+2005
String SIX_PER_EM_SPACE = " ";                     //        // U+2006
String FIGURE_SPACE = " ";                           //          // U+2007
String PUNCTUATION_SPACE = " ";                      //          // U+2008
String THIN_SPACE = " ";                            //         // U+2009
String HAIR_SPACE = " ";                             //          // U+200A
String ZERO_WIDTH_SPACE = " ";                      //         // U+200B
String NARROW_NO_BREAK_SPACE = " ";                //        // U+202F
String MEDIUM_MATHEMATICAL_SPACE = " ";             //         // U+205F
String BRAILLE_SPACE = "⠀";                            // ⠀          // U+2800⠀
String IDEOGRAPHIC_SPACE = " ";                        //           // U+3000
String ZERO_WIDTH_NO_BREAK_SPACE="";                   //            // U+FEFF
String CAUCASIAN_ASTRONAUT = "\uD83D\uDC68\uD83C\uDFFB\u200D\uD83D\uDE80"; // 👨🏻‍🚀

이상하게 티스토리에 붙이니깐 안보안다..
자 그럼 테스트코드까지 짜는건 좀 과한거같고.. 테스트 패키지에서 println정도만 찍어봤다
그리고 자바에서 whitespace를 제거하는 대표적인 2가지 메서드를 활용했다
trim, strip

String.trim()
String.strip()


테스트는 이런식으로 공백 ~ 우주비행사까지 문자열을 앞뒤로 붙여서 테스트를 해봤다

String str1 = SPACE + "HELLO" + SPACE;
String trimStr1 = str1.trim();
String stripStr1 = str1.strip();
System.out.println("<SPACE>원본 문자열 : '" + str1 + "'");
System.out.println("<SPACE>trim 문자열 : '" + trimStr1 + "'");
System.out.println("<SPACE>strip 문자열 : '" + stripStr1 + "'");
System.out.println();

<SPACE>원본 문자열 : ' HELLO '
<SPACE>trim 문자열 : 'HELLO'
<SPACE>strip 문자열 : 'HELLO'

<NO_BREAK_SPACE>원본 문자열 : ' HELLO '
<NO_BREAK_SPACE>trim 문자열 : ' HELLO '
<NO_BREAK_SPACE>strip 문자열 : ' HELLO '

<OGHAM_SPACE_MARK>원본 문자열 : ' HELLO '
<OGHAM_SPACE_MARK>trim 문자열 : ' HELLO '
<OGHAM_SPACE_MARK>strip 문자열 : 'HELLO'

<MONGOLIAN_VOWEL_SEPARATOR>원본 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>trim 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>strip 문자열 : '᠎HELLO᠎'

<EN_QUAD>원본 문자열 : ' HELLO '
<EN_QUAD>trim 문자열 : ' HELLO '
<EN_QUAD>strip 문자열 : 'HELLO'

<EM_QUAD>원본 문자열 : ' HELLO '
<EM_QUAD>trim 문자열 : ' HELLO '
<EM_QUAD>strip 문자열 : 'HELLO'

<EN_SPACE>원본 문자열 : ' HELLO '
<EN_SPACE>trim 문자열 : ' HELLO '
<EN_SPACE>strip 문자열 : 'HELLO'

<EM_SPACE>원본 문자열 : ' HELLO '
<EM_SPACE>trim 문자열 : ' HELLO '
<EM_SPACE>strip 문자열 : 'HELLO'

<THREE_PER_EM_SPACE>원본 문자열 : ' HELLO '
<THREE_PER_EM_SPACE>trim 문자열 : ' HELLO '
<THREE_PER_EM_SPACE>strip 문자열 : 'HELLO'

<FOUR_PER_EM_SPACE>원본 문자열 : ' HELLO '
<FOUR_PER_EM_SPACE>trim 문자열 : ' HELLO '
<FOUR_PER_EM_SPACE>strip 문자열 : 'HELLO'

<SIX_PER_EM_SPACE>원본 문자열 : ' HELLO '
<SIX_PER_EM_SPACE>trim 문자열 : ' HELLO '
<SIX_PER_EM_SPACE>strip 문자열 : 'HELLO'

<FIGURE_SPACE>원본 문자열 : ' HELLO '
<FIGURE_SPACE>trim 문자열 : ' HELLO '
<FIGURE_SPACE>strip 문자열 : ' HELLO '

<PUNCTUATION_SPACE>원본 문자열 : ' HELLO '
<PUNCTUATION_SPACE>trim 문자열 : ' HELLO '
<PUNCTUATION_SPACE>strip 문자열 : 'HELLO'

<THIN_SPACE>원본 문자열 : ' HELLO '
<THIN_SPACE>trim 문자열 : ' HELLO '
<THIN_SPACE>strip 문자열 : 'HELLO'

<HAIR_SPACE>원본 문자열 : ' HELLO '
<HAIR_SPACE>trim 문자열 : ' HELLO '
<HAIR_SPACE>strip 문자열 : 'HELLO'

<ZERO_WIDTH_SPACE>원본 문자열 : ' HELLO '
<ZERO_WIDTH_SPACE>trim 문자열 : ' HELLO '
<ZERO_WIDTH_SPACE>strip 문자열 : 'HELLO'

<NARROW_NO_BREAK_SPACE>원본 문자열 : ' HELLO '
<NARROW_NO_BREAK_SPACE>trim 문자열 : ' HELLO '
<NARROW_NO_BREAK_SPACE>strip 문자열 : ' HELLO '

<MEDIUM_MATHEMATICAL_SPACE>원본 문자열 : ' HELLO '
<MEDIUM_MATHEMATICAL_SPACE>trim 문자열 : ' HELLO '
<MEDIUM_MATHEMATICAL_SPACE>strip 문자열 : 'HELLO'

<BRAILLE_SPACE>원본 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>trim 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>strip 문자열 : '⠀HELLO⠀'

<IDEOGRAPHIC_SPACE>원본 문자열 : ' HELLO '
<IDEOGRAPHIC_SPACE>trim 문자열 : ' HELLO '
<IDEOGRAPHIC_SPACE>strip 문자열 : 'HELLO'

<ZERO_WIDTH_NO_BREAK_SPACE>원본 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>trim 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>strip 문자열 : 'HELLO'

<CAUCASIAN_ASTRONAUT>원본 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>trim 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>strip 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'

자, 우리는 여기에서 몇가지 특이점을 볼 수 있다
두 메서드의 동작에 차이가 있다는 것, trim으로 제거되지 않는 공백, strip으로도 제거되지 않는 공백이 있다는 사실이다
왜 이 두개 함수에서 차이가 발생할까?

trim()은 unicode가 0020(16진수)이하인 캐릭터만 제거한다고 나와 있다
strip()의 경우는 모든 앞(leading)과 뒤(trailling)의 공백을 제거한다고 나와있다

준비된 인텔리제이 스크린샷에서 보면 16진수를 오름차순으로 정렬해놨다
결국 trim()은 여기에서 SPACE만 제거할 수 있었다는 말이 된다
아마 화면에 나오지 않는 공백도 있기때문에 몇몇 공백들에서는 제거된것처럼 보이지만 그렇지 않을것이다

자, 그럼 strip의 javadoc에 있는 모든 공백들이 제거가 된다는 말은 false이다..
내 생각에는 자바의 역사가 오래됐기도 했고, 전 국가의 모든 언어체계를 오버로딩하기에는 너무 변화가 빠르기때문이 아닌가싶다

또한 자바에서는 이 캐릭터들을 공백으로 지정해놨다
그럼 어떻게 저 지워지지 않는 공백들을 지울 수 있을까?
1. StringUtils.trimAllWhitespace(String)을 써보자
2. Regex(REGular EXpression)라고 하는 정규식과 replaceAll을 같이 써보자

그럼 2번을 위해서 쓸 수 있는 정규식은 어떤게 있을까..? StackOverFlow에서 찾아봤다
https://stackoverflow.com/questions/58656881/removing-all-non-printing-characters-by-regex

String standardRegex = "\\p{Zs}+";     // Zs is stands space separators
String horizontalRegex = "\\h+";         //  A horizontal whitespace character
//                              [\t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]
String embeddedRegex = "(?U)\\s+";     // The (?U) is an embedded flag option(UTF-8)
String posixNVRegex = "\\P{Graph}+";     // POSIX like [non-visible characters]
String posixNPRegex = "\\P{Print}+";     // POSIX like [non-printable characters]

1. Zs는 표준으로 쓰이는 공백을 제거하는 regex
2. h+는 개행 등등 세로의 공백을 제거하는 regex
3. ?U는 음..UTF-8 포맷 등에서 쓰일 수 있는 내장된 flag regex
4. Graph는 POSIX unix에서 like에도 쓰일 수 있는 눈에 보이지 않는 문자들을 캐치하는 regex
5. Print는 4와 비슷하지만, 프린터 할 수 없는 문자들을 캐치하는 regex
이정도..? 그럼 코드로 고고!!


이번에는 좀 추가했다

String str1 = SPACE + "HELLO" + SPACE;
String trimStr1 = str1.trim();
String stripStr1 = str1.strip();
String utilStr1 = StringUtils.trimAllWhitespace(str1);
String standardRegex1 = str1.replaceAll(standardRegex,"");
String horizontalRegex1 = str1.replaceAll(horizontalRegex,"");
String embeddedRegex1 = str1.replaceAll(embeddedRegex,"");
String posixNVRegex1 = str1.replaceAll(posixNVRegex,"");
String posixNPRegex1 = str1.replaceAll(posixNPRegex,"");
System.out.println("<SPACE>원본 문자열 : '" + str1 + "'");
System.out.println("<SPACE>trim 문자열 : '" + trimStr1 + "'");
System.out.println("<SPACE>strip 문자열 : '" + stripStr1 + "'");
System.out.println("<SPACE>StringUtils 문자열 : '" + utilStr1 + "'");
System.out.println("<SPACE>replaceAll(\\p{Zs}+) 문자열 : '" + standardRegex1 + "'");
System.out.println("<SPACE>replaceAll(\\h+) 문자열 : '" + horizontalRegex1 + "'");
System.out.println("<SPACE>replaceAll(?U)\\s+ 문자열 : '" + embeddedRegex1 + "'");
System.out.println("<SPACE>replaceAll(\\P{Graph}+) 문자열 : '" + posixNVRegex1 + "'");
System.out.println("<SPACE>replaceAll(\\P{Print}+) 문자열 : '" + posixNPRegex1 + "'");
System.out.println();

대강 이렇게 테스트해보았다

<결과>

<SPACE>원본 문자열 : ' HELLO '
<SPACE>trim 문자열 : 'HELLO'
<SPACE>strip 문자열 : 'HELLO'
<SPACE>StringUtils 문자열 : 'HELLO'
<SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<SPACE>replaceAll(\P{Print}+) 문자열 : ' HELLO '

<NO_BREAK_SPACE>원본 문자열 : ' HELLO '
<NO_BREAK_SPACE>trim 문자열 : ' HELLO '
<NO_BREAK_SPACE>strip 문자열 : ' HELLO '
<NO_BREAK_SPACE>StringUtils 문자열 : ' HELLO '
<NO_BREAK_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<NO_BREAK_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<NO_BREAK_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<NO_BREAK_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<NO_BREAK_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<OGHAM_SPACE_MARK>원본 문자열 : ' HELLO '
<OGHAM_SPACE_MARK>trim 문자열 : ' HELLO '
<OGHAM_SPACE_MARK>strip 문자열 : 'HELLO'
<OGHAM_SPACE_MARK>StringUtils 문자열 : 'HELLO'
<OGHAM_SPACE_MARK>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<OGHAM_SPACE_MARK>replaceAll(\h+) 문자열 : 'HELLO'
<OGHAM_SPACE_MARK>replaceAll(?U)\s+ 문자열 : 'HELLO'
<OGHAM_SPACE_MARK>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<OGHAM_SPACE_MARK>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<MONGOLIAN_VOWEL_SEPARATOR>원본 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>trim 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>strip 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>StringUtils 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>replaceAll(\p{Zs}+) 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>replaceAll(\h+) 문자열 : 'HELLO'
<MONGOLIAN_VOWEL_SEPARATOR>replaceAll(?U)\s+ 문자열 : '᠎HELLO᠎'
<MONGOLIAN_VOWEL_SEPARATOR>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<MONGOLIAN_VOWEL_SEPARATOR>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<EN_QUAD>원본 문자열 : ' HELLO '
<EN_QUAD>trim 문자열 : ' HELLO '
<EN_QUAD>strip 문자열 : 'HELLO'
<EN_QUAD>StringUtils 문자열 : 'HELLO'
<EN_QUAD>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<EN_QUAD>replaceAll(\h+) 문자열 : 'HELLO'
<EN_QUAD>replaceAll(?U)\s+ 문자열 : 'HELLO'
<EN_QUAD>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<EN_QUAD>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<EM_QUAD>원본 문자열 : ' HELLO '
<EM_QUAD>trim 문자열 : ' HELLO '
<EM_QUAD>strip 문자열 : 'HELLO'
<EM_QUAD>StringUtils 문자열 : 'HELLO'
<EM_QUAD>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<EM_QUAD>replaceAll(\h+) 문자열 : 'HELLO'
<EM_QUAD>replaceAll(?U)\s+ 문자열 : 'HELLO'
<EM_QUAD>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<EM_QUAD>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<EN_SPACE>원본 문자열 : ' HELLO '
<EN_SPACE>trim 문자열 : ' HELLO '
<EN_SPACE>strip 문자열 : 'HELLO'
<EN_SPACE>StringUtils 문자열 : 'HELLO'
<EN_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<EN_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<EN_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<EN_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<EN_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<EM_SPACE>원본 문자열 : ' HELLO '
<EM_SPACE>trim 문자열 : ' HELLO '
<EM_SPACE>strip 문자열 : 'HELLO'
<EM_SPACE>StringUtils 문자열 : 'HELLO'
<EM_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<EM_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<EM_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<EM_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<EM_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<THREE_PER_EM_SPACE>원본 문자열 : ' HELLO '
<THREE_PER_EM_SPACE>trim 문자열 : ' HELLO '
<THREE_PER_EM_SPACE>strip 문자열 : 'HELLO'
<THREE_PER_EM_SPACE>StringUtils 문자열 : 'HELLO'
<THREE_PER_EM_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<THREE_PER_EM_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<THREE_PER_EM_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<THREE_PER_EM_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<THREE_PER_EM_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<FOUR_PER_EM_SPACE>원본 문자열 : ' HELLO '
<FOUR_PER_EM_SPACE>trim 문자열 : ' HELLO '
<FOUR_PER_EM_SPACE>strip 문자열 : 'HELLO'
<FOUR_PER_EM_SPACE>StringUtils 문자열 : 'HELLO'
<FOUR_PER_EM_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<FOUR_PER_EM_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<FOUR_PER_EM_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<FOUR_PER_EM_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<FOUR_PER_EM_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<SIX_PER_EM_SPACE>원본 문자열 : ' HELLO '
<SIX_PER_EM_SPACE>trim 문자열 : ' HELLO '
<SIX_PER_EM_SPACE>strip 문자열 : 'HELLO'
<SIX_PER_EM_SPACE>StringUtils 문자열 : 'HELLO'
<SIX_PER_EM_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<SIX_PER_EM_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<SIX_PER_EM_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<SIX_PER_EM_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<SIX_PER_EM_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<FIGURE_SPACE>원본 문자열 : ' HELLO '
<FIGURE_SPACE>trim 문자열 : ' HELLO '
<FIGURE_SPACE>strip 문자열 : ' HELLO '
<FIGURE_SPACE>StringUtils 문자열 : ' HELLO '
<FIGURE_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<FIGURE_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<FIGURE_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<FIGURE_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<FIGURE_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<PUNCTUATION_SPACE>원본 문자열 : ' HELLO '
<PUNCTUATION_SPACE>trim 문자열 : ' HELLO '
<PUNCTUATION_SPACE>strip 문자열 : 'HELLO'
<PUNCTUATION_SPACE>StringUtils 문자열 : 'HELLO'
<PUNCTUATION_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<PUNCTUATION_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<PUNCTUATION_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<PUNCTUATION_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<PUNCTUATION_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<THIN_SPACE>원본 문자열 : ' HELLO '
<THIN_SPACE>trim 문자열 : ' HELLO '
<THIN_SPACE>strip 문자열 : 'HELLO'
<THIN_SPACE>StringUtils 문자열 : 'HELLO'
<THIN_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<THIN_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<THIN_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<THIN_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<THIN_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<HAIR_SPACE>원본 문자열 : ' HELLO '
<HAIR_SPACE>trim 문자열 : ' HELLO '
<HAIR_SPACE>strip 문자열 : 'HELLO'
<HAIR_SPACE>StringUtils 문자열 : 'HELLO'
<HAIR_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<HAIR_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<HAIR_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<HAIR_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<HAIR_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<ZERO_WIDTH_SPACE>원본 문자열 : ' HELLO '
<ZERO_WIDTH_SPACE>trim 문자열 : ' HELLO '
<ZERO_WIDTH_SPACE>strip 문자열 : 'HELLO'
<ZERO_WIDTH_SPACE>StringUtils 문자열 : 'HELLO'
<ZERO_WIDTH_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<ZERO_WIDTH_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<ZERO_WIDTH_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<ZERO_WIDTH_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<ZERO_WIDTH_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<NARROW_NO_BREAK_SPACE>원본 문자열 : ' HELLO '
<NARROW_NO_BREAK_SPACE>trim 문자열 : ' HELLO '
<NARROW_NO_BREAK_SPACE>strip 문자열 : ' HELLO '
<NARROW_NO_BREAK_SPACE>StringUtils 문자열 : ' HELLO '
<NARROW_NO_BREAK_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<NARROW_NO_BREAK_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<NARROW_NO_BREAK_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<NARROW_NO_BREAK_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<NARROW_NO_BREAK_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<MEDIUM_MATHEMATICAL_SPACE>원본 문자열 : ' HELLO '
<MEDIUM_MATHEMATICAL_SPACE>trim 문자열 : ' HELLO '
<MEDIUM_MATHEMATICAL_SPACE>strip 문자열 : 'HELLO'
<MEDIUM_MATHEMATICAL_SPACE>StringUtils 문자열 : 'HELLO'
<MEDIUM_MATHEMATICAL_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<MEDIUM_MATHEMATICAL_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<MEDIUM_MATHEMATICAL_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<MEDIUM_MATHEMATICAL_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<MEDIUM_MATHEMATICAL_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<BRAILLE_SPACE>원본 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>trim 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>strip 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>StringUtils 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>replaceAll(\p{Zs}+) 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>replaceAll(\h+) 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>replaceAll(?U)\s+ 문자열 : '⠀HELLO⠀'
<BRAILLE_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<BRAILLE_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<IDEOGRAPHIC_SPACE>원본 문자열 : ' HELLO '
<IDEOGRAPHIC_SPACE>trim 문자열 : ' HELLO '
<IDEOGRAPHIC_SPACE>strip 문자열 : 'HELLO'
<IDEOGRAPHIC_SPACE>StringUtils 문자열 : 'HELLO'
<IDEOGRAPHIC_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<IDEOGRAPHIC_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<IDEOGRAPHIC_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<IDEOGRAPHIC_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<IDEOGRAPHIC_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<ZERO_WIDTH_NO_BREAK_SPACE>원본 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>trim 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>strip 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>StringUtils 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>replaceAll(\p{Zs}+) 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>replaceAll(\h+) 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>replaceAll(?U)\s+ 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<ZERO_WIDTH_NO_BREAK_SPACE>replaceAll(\P{Print}+) 문자열 : 'HELLO'

<CAUCASIAN_ASTRONAUT>원본 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>trim 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>strip 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>StringUtils 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>replaceAll(\p{Zs}+) 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>replaceAll(\h+) 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>replaceAll(?U)\s+ 문자열 : '👨🏻‍🚀HELLO👨🏻‍🚀'
<CAUCASIAN_ASTRONAUT>replaceAll(\P{Graph}+) 문자열 : 'HELLO'
<CAUCASIAN_ASTRONAUT>replaceAll(\P{Print}+) 문자열 : 'HELLO'

결론은 StringUtils.trimAllWhitespace()를 이용하더라도, 표준 Zs를 이용하더라도 제거되지 않는 공백문자들이 존재한다는 것이다
=> BRAILLE_SPACE, CAUCASIAN_ASTRONAUT 등등...
String.strip()만 믿고 공백제거가 완벽하게 잘 될것이라 생각하면 경기도 오산!!
깔끔하게 \P{Graph}+ 정규식으로 없애보는건 어떨까..?

+

JavaScript에는 최신버전에 replaceAll이 있지만, 기본적으로 최신브라우저(Node)를 사용하지 않거나, 크로스브라우징 등의 이유로 원래 있던 replace에 regex를 같이 써줘야 safe하게 적용할 수 있다
그리고 .replace함수는 패턴과 만나는 맨 앞의 1개만 지워준다
이게 무슨말이냐하면...

010-1234-5678에서 -가 전부 공백으로 치환되기를 기대함
=> 맨 앞에 -만 공백으로 바뀜

그럼 어떻게 해야할까?
1번 정규식 패턴에서 '대신 /로 사용하고 뒤에 g 옵션(global)을 붙이면 전체 스트링에 대해서 패턴매칭을 진행한다
* g : 발생할 모든 패턴에 대한 전역 검색

단순히 입력값으로 숫자만 들어오면 g로 전체 문자열만 대치시키면 상관없다
하지만 프론트작업의 대부분은 문자가 들어온다 그리고 value값은 대부분 영어이다..!
영어는 대/소문자가 존재한다
대/소문자를 구분하지 않는 옵션도 있지 않을까?
* i : 대/소문자 구분 안함

1. rege_banana는 모든 a또는 A를 p로 바꿨다(g, i옵션 있음)
2. rege_banana2는 모든 소문자 a만 p로 바꿨다(g 옵션만 있음)

이제 프론트단에서 단순히 문자열 내의 모든 공백을 제거하는 간단한 코드는 이거다(Ts)

const testStr: str = 't e st'
testStr.replace(/\s/gi,'')        : 문자열 내의 모든 공백 제거
=> test

또 - 같은게 아닌 /를 제거하고 싶을수도 있을것이다
그럴땐 escape String( \ )과 함께 사용해주면 된다

그리고 들어온 문자를 일정한 형식으로 바꾸고 싶을땐 replace와 $를 같이 쓰면 좋다

사업자번호는 3자리-2자리-5자리이다
그럼 끝!!!!

참조
https://en.wikipedia.org/wiki/Whitespace_character

Whitespace character - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Any character in typography representing a blank space "Dot space" redirects here. For the animated film, see Dot in Space. "␣" redirects here. Not to be confused with ⌴. In comput

en.wikipedia.org

https://unicode-table.com/en/search/?q=ZERO+WIDTH+SPACE

Search

Unicode web service for character search. Find, copy and paste your favorite characters: 😎 Emoji, ❤ Hearts, 💲 Currencies, → Arrows, ★ Stars and many others 🚩

unicode-table.com

https://jkorpela.fi/chars/spaces.html

Unicode spaces

This document lists the various space characters in Unicode. For a description, consult chapter 6 Writing Systems and Punctuation and block description General Punctuation in the Unicode standard. This document also lists three characters that have no wid

jkorpela.fi

https://qwerty.dev/whitespace/

qwerty-site

My premium Nuxt.js project

qwerty.dev

https://stackoverflow.com/questions/58656881/removing-all-non-printing-characters-by-regex

removing all non-printing characters by regex

I have files which contain non-printing characters such as \u2066-\u2069 (directional formatting) and \u2000-\u2009 (spaces of various widths, e.g. &thinsp; ). Is it possible to remove (or repl...

stackoverflow.com

https://www.tutorialspoint.com/posix-character-classes-p-print-java-regex

Posix character classes p{Print} Java regex

Posix character classes p{Print} Java regex This class matches all the printable characters. Example 1  Live Demo import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class PrintableCharacters {    public stat

www.tutorialspoint.com

320x100

댓글