알파벳, 숫자, 특수문자가 섞여 있는 문자열 S가 주어졌을 때, 이를 세 개의 서로 다른 문자열 S1, S2, S3로 분리하는 프로그램을 작성해야 합니다. 각 문자열의 역할은 다음과 같습니다.
- S1: 원본 문자열 S에 포함된 모든 알파벳을 담습니다.
- S2: 원본 문자열 S에 포함된 모든 숫자를 담습니다.
- S3: 원본 문자열 S에 포함된 모든 특수문자를 담습니다.
이때 중요한 조건은, 세 문자열의 문자들이 입력 문자열에서 등장한 순서를 그대로 유지해야 한다는 점입니다.
예제 코드
아래 코드는 문자열을 한 글자씩 순회하면서 reduce 메서드로 각 문자를 해당 그룹에 누적하는 방식으로 문제를 해결합니다.
const str = "Th!s String C0nt@1ns d1fferent ch@ract5rs";
const seperateCharacters = str => {
const strArr = str.split("");
return strArr.reduce((acc, val) => {
let { numbers, alpha, special } = acc;
if (+val) {
// 숫자인 경우
numbers += val;
} else if (val.toUpperCase() !== val.toLowerCase()) {
// 대소문자 변환 결과가 다르면 알파벳
alpha += val;
} else {
// 그 외에는 특수문자
special += val;
}
return { numbers, alpha, special };
}, {
numbers: '',
alpha: '',
special: ''
});
};
console.log(seperateCharacters(str));코드 동작 원리
str.split("")로 문자열을 개별 문자 배열로 만듭니다.reduce()를 사용해 각 문자를 순서대로 검사하며, 숫자·알파벳·특수문자 세 가지 키를 가진 객체에 이어 붙입니다.+val이 참이면 숫자로 판단합니다. 단, 공백과 같은 일부 값도 숫자로 암시적 변환될 수 있으므로 실무에서는 정규식(/[0-9]/) 사용을 권장합니다.val.toUpperCase() !== val.toLowerCase()는 해당 문자가 알파벳인지 확인하는 기법입니다. 알파벳은 대소문자 변환 시 값이 달라지지만, 특수문자는 변환 후에도 동일하게 유지됩니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
{
numbers: '115',
alpha: 'ThsStringCntnsdfferentchractrs',
special: '! 0@ @'
}정규식을 활용한 대안
더 직관적인 방법으로 정규식과 match()를 활용할 수도 있습니다.
const str = "Th!s String C0nt@1ns d1fferent ch@ract5rs";
const numbers = str.match(/[0-9]/g).join('');
const alpha = str.match(/[a-zA-Z]/g).join('');
const special = str.replace(/[a-zA-Z0-9]/g, '');
console.log(numbers); // '115'
console.log(alpha); // 'ThsStringCntnsdfferentchractrs'
console.log(special); // '! @ @'정규식 방식은 의도가 명확하게 드러나고 가독성이 좋다는 장점이 있어, 실제 프로젝트에서 더 널리 사용됩니다.