Intl.Segmenter 사용하여 자바스크립트(Javascript) 문자열 나누기
안녕하세요?
최근에 계속해서 Intl 객체를 이용해서 좋은 결과를 내고 있는데요.
오늘은 문자열 나누기에 있어 언어별 특성대로 나눌 수 있는 예를 공부해 볼까 합니다.
split() 메서드
기존에는 문자열을 나누는 함수는 split 함수를 썼었는데요.
'Hello! World? friend.'.split(/[.!?]/)
// [ 'Hello', ' World', ' friend', '' ]
위 코드를 보시면 split 함수에서 옵션을 둬서 문자열을 나눴는데요.
한글의 경우 어떻게 될까요?
'안녕! 세계야? 친구들.'.split(/[.!?]/)
// [ '안녕', ' 세계야', ' 친구들', '' ]
뭔가 잘 되는 거 같은데 마지막에 뭔가 하나 추가되었네요.
일본어를 예로 들어 볼까요?
'吾輩は猫である.名前はたぬき.'.split(/[.]/)
;['吾輩は猫である', '名前はたぬき', '']
만족스럽지는 않지만 나름 문자열 나누기의 기능을 하고 있는데요.
좀 더 강력한 기능이 Intl.Segmenter 객체에 있습니다.
좀 더 자세히 살펴보겠습니다.
Intl.Segmenter
"Segmenter"이라는 말의 뜻은 "분할기"라는 뜻이네요.
예를 들어 살펴보겠습니다.
const segmenterKo = new Intl.Segmenter('ko-KR', {
granularity: 'word',
})
const results = segmenterKo.segment(
'안녕하세요? 제 블로그에 오신 걸 환영합니다!',
)
console.log(Array.from(results).map(s => s.segment))
// ['안녕하세요', '?', ' ', '제', ' ', '블로그에', ' ', '오신', ' ', '걸', ' ', '환영합니다', '!']
어떤가요? 정말 깔끔하게 분리가 되었네요.
granularity 옵션에는 3가지가 들어갈 수 있는데요.
"sentence", "word", "grapheme"입니다.
각각의 예를 들어 볼까요?
const segmenterKo = new Intl.Segmenter('ko-KR', {
granularity: 'sentence',
})
const results = segmenterKo.segment(
'안녕하세요? 제 블로그에 오신 걸 환영합니다!',
)
console.log(Array.from(results).map(s => s.segment))
// [ '안녕하세요? ', '제 블로그에 오신 걸 환영합니다!' ]
const segmenterKo = new Intl.Segmenter('ko-KR', {
granularity: 'grapheme',
})
const results = segmenterKo.segment(
'안녕하세요? 제 블로그에 오신 걸 환영합니다!',
)
console.log(Array.from(results).map(s => s.segment))
// [
// '안', '녕', '하', '세', '요',
// '?', ' ', '제', ' ', '블',
// '로', '그', '에', ' ', '오',
// '신', ' ', '걸', ' ', '환',
// '영', '합', '니', '다', '!'
// ]
예를 들어보니까 정확히 어떻게 작동되는지 쉽게 이해할 수 있네요.
주의하실 점은 results 값이 Segments 라는 객체인데요.
이 객체는 정말 긴데요. 여기서 우리가 가져올 거는 바로 segment 항목입니다.
그래서 Array.map 함수로 돌려서 원하는 값을 얻어야 합니다.
팁으로 문자열의 isWordLike 메서드를 쓰면 빈칸은 없애고 단어만 골라낼 수 있습니다.
const segmenterKo = new Intl.Segmenter('ko-KR', {
granularity: 'word',
})
const results = segmenterKo.segment(
'안녕하세요? 제 블로그에 오신 걸 환영합니다!',
)
console.log([...results].filter(s => s.isWordLike).map(s => s.segment))
// [ '안녕하세요', '제', '블로그에', '오신', '걸', '환영합니다' ]
Emojis 분할해 보기
그럼 유니코드의 이모지(Emojis)도 분할해 볼까요?
const emojis = '🫣🫵👨👨👦👦'
// Split by code units
console.log(emojis.split(''))
// [
// '\ud83e', '\udee3', '\ud83e',
// '\udef5', '\ud83d', '\udc68',
// '', '\ud83d', '\udc68',
// '', '\ud83d', '\udc66',
// '', '\ud83d', '\udc66'
// ]
// Split by graphemes
const segmenter = new Intl.Segmenter('en', {
granularity: 'grapheme',
})
const segments = segmenter.segment(emojis)
console.log(Array.from(segmenter.segment(emojis), s => s.segment))
// [ '🫣', '🫵', '👨👨👦👦' ]
역시나 이모지에서도 정확히 작동하네요.
그럼.