[HTML,JavaScript] 글자수세기, Byte 세기 구현(정규식 사용 연습)

김의진·2021년 10월 4일
0

HTML, JavaScrip를 통해 글자수세기와 Byte세기를 구현해보도록 하겠습니다.
JavaScript의 정규식 사용 공부에 유용하리라 생각합니다.
저는 <발표시간 계산기>를 만들면서, 추가해본 기능이었습니다.

https://www.speechtime.co.kr/

이 사이트에서 글자수세기, Byte세기가 어떻게 작동되는지 간략히 파악해보시면 좋을 듯 합니다.

본격적으로 시작합니다.

구현할 것

  1. 텍스트 박스를 만듭니다.
  2. 텍스트 박스에 글자를 넣었을 때, 자동으로 글자수세기와 Byte세기가 작동되어 화면에 표시되도록 합니다.

글자수세기의 규칙

  1. 공백포함 : 모든 언어, 공백, 특수문자를 1글자로 취급합니다.

  2. Naver 글자수세기는 줄바꿈을 1글자로 취급, 한글에서는 줄바꿈을 글자로 취급하지 않았습니다.

(제 개인적인 의견으로는 줄바꿈을 글자수로 취급하는 것이 맞다고 생각합니다. 만약, 줄바꿈을 글자수로 세지 않는다면, 온점을 찍고, 띄어쓰기를 하지 않은 채 줄바꿈을 하면, 문장을 이어주는 데 어떠한 공백도 필요하지 않은 셈이지요. 그래서 저는 Naver의 기준을 따랐습니다.)

  1. 공백미포함 : 공백, 줄바꿈을 제외한 모든 글자를 1글자로 취급합니다.

바이트(Byte)세기의 규칙

  1. 공백포함 : 한글, 한자, 중국어, 일본어는 2글자로, 나머지 언어와 특수문자, 공백은 1글자로 취급합니다.

  2. 공백미포함 : 공백과 줄바꿈을 제외합니다.

시작합니다.

<!-- textarea는 텍스트를 넣는 박스를 만드는 함수입니다. --!>
<textarea placeholder="⦁ 텍스트를 입력하시면, 글자수와 Byte를 반환합니다." class="textInput"></textarea>
<!-- 출력해보일 span을 만들어둡니다. --!>
<span class="lengthWblank">0 자 / 0 Byte</span>
<span class="lengthWOblank">0 자 / 0 Byte</span>

HTML에서 textarea와 출력 element를 간단히 만듭니다.

let textInput = document.querySelector('.textInput');
let lengthWOblank = document.querySelector('.lengthWOblank');
let lengthWblank = document.querySelector('.lengthWblank');

// input 또는 keyup이 사용될 수 있을텐데,
// keyup은 키보드 자판이 눌러진 후 에 발생하는 이벤트입니다. 그러므로 마우스 오른쪽 클릭 후 붙여넣기했을 때는 발생하지 않습니다.
// 그러므로 input을 사용해야합니다. input은 박스내에 입력되는 모든 반응 이벤트입니다.
textInput.addEventListener(('input'), ()=>{
    // 글자수세기(공백포함)
    // 공백포함일때, 글자수는 간단하게 textiInput.value 갚의 길이를 구해줍니다.
    // byte수는 밑에서 byteCounter() 함수를 정의하여 사용할 것입니다.
    // .innerHTML or .innerText 는 span, p, div, button 등의 안에 있는 글자를 가리키고,
    // .value는 input, textarea, 등 입력이 가능한 박스 안에 들어있는 값을 가리킵니다.
    lengthWblank.innerHTML = `${textInput.value.length} 자 / ${byteCounter(textInput.value,1)} Byte`;

    // 글자수세기(공백미포함)
    // 공백과 줄바꿈을 제외해야 합니다. 이때 정규식을 사용합니다. 
    // \s 는 줄바꿈, 공백 또는 탭과 같은 글자가 포함되어 있지 않은 문자를 말합니다.
    // + 는 1개 이상의 것을 의미합니다. 글자가 2개 연속있거나, 줄바꿈이 3개 연속있거나 하는 것들을 모두 가리킵니다.
    // 이를 / / 사이에 넣으면 정규식이 됩니다. 
    // g 는 global 을 의미하고, textInput.value에 있는 모든 \s+ 를 말합니다.
    // 즉, /\s+/g를 ""로 replace 해줍니다.
    // Byte세기는 위와 같이 함수를 정의하여 사용할 겁니다.
    lengthWOblank.innerHTML = `${textInput.value.replace(/\s+/g, "").length} 자 / ${byteCounter(textInput.value.replace(/\s+/g,""),0)} Byte`;
function byteCounter(text, blank=0) {
    // blank === 0 -> 공백 미포함  ,  blank !== 1 -> 공백 포함
    let byte = 0;
    // byte 를 0으로 두고, 한글자씩 체크하면서 한자 한문 한글이면 2를 올려주고, 그 외는 1을 올려주겠습니다.
    if (blank==0) {
        // 공백 미포함일 때는, 미리 줄바꿈과 공백을 빈칸으로 처리합니다.
        text = text.replace(/\s+/g,"");
    } 
    
    for(let i=0; i<text.length;i++) {
        // 정규식.test() 함수는 인수가 정규식을 만족하는지 판단하여 true or false 값을 반환합니다.
        // 한글표현 정규식 : ㄱ-ㅎㅏ-ㅣ가-힣
        // 한자표현 정규식 : 一-龥
        // 일본어표현 정규식 : ぁ-ゔァ-ヴー々〆〤
        // 이 모든것을 /[]/ 안에 포함시켜서 연달아 써주면 "or" 처리됩니다.
        // 한, 중, 일 언어라면, byte를 2 더해주고, 아니라면 1을 더해주고, 최종적으로 byte를 return 합니다.
        if (/[ㄱ-ㅎㅏ-ㅣ가-힣一-龥ぁ-ゔァ-ヴー々〆〤]/.test(text[i])) {
            byte = byte+2
        } else {
            byte++
        }
    }
    return byte
}

위 정규식이 포함된 if 는 이렇게 표현할 수도 있을 것입니다.

if (/[\sa-zA-Z0-9`~!@#$%^&*()_+-={}\[\];':",./<>?]/.test(text[i])) {
            byte++
        } else {
            byte= byte+2
        }

엄밀하게 체크하기 위하여, 키보드에 있지 않는 특수문자를 모두 2byte로 취급하는 방법입니다.

키보드에 있는 문자는 `~!@#$%^&*()_+-={}[]:";'<>?,./ 가 전부이고

키보드에 없는 문자는 ⓑ ★ □ 등이 될 수 있겠지요.

특수문자까지 고려하여 좀 더 완벽하게 하고 싶다면, 이 방법을 택해볼 수도 있을 것입니다.

영어, 숫자정규식

추가로,

영어표현 정규식 : a-zA-Z
숫자표현 정규식 : 0-9

정규식은 자주 쓰면서 자연스레 외우는 방법이 좋을 것이라고 생각합니다.
처음 보면 복잡하기 때문에 암기가 힘듭니다.
그러므로 암기하기 보다는, 구조를 파악하면 언제든 찾아서 사용할 수 있을 겁니다.

마치며

위 코드를 그대로 입력하시면, 생각했던 대로 구현될 것입니다.
이 정도면 보통의 자기소개서에 한하여, 네이버 글자수세기와 동일하게 작용합니다.
한중일, 알파벳 제외 언어이거나 특수문자, 이모지 등이 들어가면, 조금 다른 결과가 나올 수 있습니다.

오류가 있거나, 제가 고려하지 못 한 부분이 있다면 댓글로 적어주시면 감사하겠습니다.

profile
안녕하세요

0개의 댓글