자바스크립트 기초 #6 문자열과 템플릿 리터럴
#5 객체와 배열 에서 데이터를 묶는 두 자료구조를 봤습니다. 이번 글에서는 문자열 하나를 깊이 살펴봅니다. 자주 쓰는 메서드, 템플릿 리터럴, 그리고 정규식 기본까지 정리합니다.
문자열 만들기 — 따옴표 세 가지 #
자바스크립트에서 문자열을 만드는 따옴표는 셋입니다.
const a = '작은따옴표';
const b = "큰따옴표";
const c = `백틱(템플릿 리터럴)`;'(작은) 와 "(큰)는 의미상 차이 없습니다. 팀 컨벤션 따라 한 종류로 통일 하는 게 보통입니다. 이 시리즈는 작은따옴표를 씁니다.
세 번째인 백틱은 템플릿 리터럴 이라 부르는 강력한 문자열 형태인데, 잠시 뒤에 자세히 봅니다.
자주 쓰는 메서드 #
길이와 인덱스 접근 #
const s = '자바스크립트';
s.length; // 7
s[0]; // '자'
s.at(0); // '자'
s.at(-1); // '트' (음수 인덱스 — at만 가능)
at()은 ES2022에 추가된 메서드. 음수 인덱스로 끝에서부터 접근할 수 있습니다. s[s.length - 1]보다 짧고 명확합니다.
찾기 #
const s = 'hello world';
s.includes('world'); // true
s.indexOf('world'); // 6
s.indexOf('foo'); // -1 (없으면 -1)
s.startsWith('hello'); // true
s.endsWith('world'); // true
**검색은 거의 항상 includes / startsWith / endsWith**가 직관적입니다. indexOf는 위치까지 알아야 할 때만.
자르기 / 추출 #
const s = 'hello world';
s.slice(0, 5); // 'hello'
s.slice(6); // 'world'
s.slice(-5); // 'world' (끝에서 5자)
s.substring(0, 5); // 'hello' (slice과 거의 같음)
옛날에는 substring/substr/slice가 미묘하게 달랐는데, 새 코드에서는 slice 하나로 통일 하는 게 좋습니다. 음수 인덱스도 받고 가장 직관적입니다.
변환 / 정리 #
const s = ' Hello World ';
s.trim(); // 'Hello World'
s.trimStart(); // 'Hello World '
s.trimEnd(); // ' Hello World'
s.toLowerCase(); // ' hello world '
s.toUpperCase(); // ' HELLO WORLD '
s.replaceAll(' ', '_'); // '__Hello_World__'
replaceAll은 ES2021에 추가됐습니다. 옛날에는 replace(/g/)로 정규식을 써야 했는데 이제 단순 치환은 이쪽이 깔끔합니다.
분할 / 결합 #
const s = '사과,바나나,포도';
s.split(','); // ['사과', '바나나', '포도']
['사과', '바나나'].join(','); // '사과,바나나'
// 한 글자씩
'hello'.split(''); // ['h', 'e', 'l', 'l', 'o']
// 빈 문자열로 합치기
['h', 'i'].join(''); // 'hi'
split('') 한 글자씩 분리는 ASCII 외 문자(이모지 등)에서는 깨질 수 있습니다. 이모지/한자까지 안전한 분리는 [...s] (spread)나 Array.from(s)를 씁니다.
const s = 'a😀b';
s.split(''); // ['a', '\uD83D', '\uDE00', 'b'] ← 깨짐
[...s]; // ['a', '😀', 'b']
Array.from(s); // ['a', '😀', 'b']
템플릿 리터럴 — 백틱의 진가 #
+로 문자열을 합치는 경우는 거의 모두 백틱이 더 깔끔합니다.
const name = '커티스';
const age = 30;
// + 연산
const a = '안녕, ' + name + ' (' + age + ')';
// 템플릿 리터럴
const b = `안녕, ${name} (${age})`;${...} 안에는 어떤 표현식이든 들어갈 수 있습니다.
const items = ['사과', '바나나', '포도'];
`총 ${items.length}개`;
`첫 번째: ${items[0]}`;
`합: ${1 + 2 + 3}`;
`상태: ${age >= 18 ? '성인' : '미성년'}`;여러 줄 문자열 #
const html = `
<div>
<h1>제목</h1>
<p>본문</p>
</div>
`;옛날에는 '<div>\n<h1>...'처럼 \n으로 줄바꿈을 직접 적었습니다. 백틱은 줄바꿈이 그대로 들어갑니다.
Tagged Template — 함수 호출 #
조금 고급 사용법. 백틱 앞에 함수를 두면 템플릿이 그 함수의 인자로 전달됩니다.
function highlight(strings, ...values) {
return strings.reduce((acc, s, i) => {
return acc + s + (values[i] !== undefined ? `[${values[i]}]` : '');
}, '');
}
const name = '커티스';
const age = 30;
highlight`이름은 ${name}, 나이는 ${age}입니다`;
// '이름은 [커티스], 나이는 [30]입니다'
html 같은 라이브러리에서 SQL/HTML 인젝션을 막기 위해 자주 쓰는 패턴입니다. 처음에는 익숙하지 않아도 OK — 만나면 그제서야 자세히 보면 됩니다.
숫자/문자열 변환 #
String(42); // '42'
(42).toString(); // '42'
`${42}`; // '42' — 가장 흔한 관용구
Number('42'); // 42
parseInt('42px'); // 42 — 앞부분만
parseFloat('3.14'); // 3.14
+'42'; // 42 — 단항 + 연산자
Number('abc'); // NaN
parseInt('abc'); // NaN
Number(...)는 전체가 숫자가 아니면 NaN. parseInt/parseFloat는 앞에서부터 가능한 만큼 파싱합니다. 입력에 42px 같은 단위가 붙어 있으면 후자가 적합합니다.
정규식 — 패턴 매칭 #
/패턴/플래그 형태의 리터럴.
const re = /hello/i; // 대소문자 무시
'Hello World'.match(re); // ['Hello', ...]
re.test('Hi'); // false
re.test('Hello'); // true
자주 쓰는 메타 문자 #
| 패턴 | 의미 |
|---|---|
. | 임의의 한 글자 |
\d | 숫자 |
\w | 단어 글자 (알파벳/숫자/_) |
\s | 공백 |
^ / $ | 줄 시작 / 끝 |
+ | 한 번 이상 |
* | 0번 이상 |
? | 0번 또는 한 번 |
[abc] | a, b, c 중 하나 |
(...) | 캡처 그룹 |
자주 쓰는 경우 #
// 이메일 형식 대충 검사
/^[^@]+@[^@]+\.[^@]+$/.test('me@example.com'); // true
// 숫자만 추출
'price: 1500원'.match(/\d+/); // ['1500', ...]
// 모든 매치
'a1 b2 c3'.matchAll(/[a-z]\d/g); // 이터러블
// 치환
'2026-05-04'.replace(/-/g, '/'); // '2026/05/04'
g 플래그는 모든 매치를 찾으라는 뜻(global). 없으면 첫 번째만 찾습니다.
캡처 그룹 #
const date = '2026-05-04';
const m = date.match(/^(\d{4})-(\d{2})-(\d{2})$/);
// m: ['2026-05-04', '2026', '05', '04', ...]
const [, year, month, day] = m;
console.log(year, month, day); // 2026 05 04
소괄호 (...) 안의 부분이 캡처 되어 결과 배열에 함께 담깁니다. 명명 그룹도 가능합니다.
const m = '2026-05-04'.match(
/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/
);
m.groups.year; // '2026'
m.groups.month; // '05'
m.groups.day; // '04'
(?<이름>...) 형태. 결과의 groups에서 이름으로 꺼내요.
정규식이 필요할 때 / 아닐 때 #
정규식은 강력하지만 읽기 어려워지기 쉽습니다. 다음 경우엔 정규식보다 일반 문자열 메서드가 거의 항상 더 좋습니다.
// 단순 검색
s.includes('foo'); // O
s.match(/foo/); // X (과함)
// 시작/끝 검사
s.startsWith('http'); // O
s.match(/^http/); // X
// 단순 치환
s.replaceAll('foo', 'bar'); // O
s.replace(/foo/g, 'bar'); // X (과함)
정규식이 빛나는 상황은 패턴이 가변적이거나 캡처가 필요한 경우입니다 — 날짜, 이메일 같은 형식 검사, 로그 파싱 등.
마무리 #
이번 글에서 정리한 내용:
- 따옴표 세 가지 —
'/"는 의미 같음,`는 템플릿 리터럴 - 자주 쓰는 메서드 —
length/at/includes/slice/split/join/replaceAll - 유니코드 안전한 분리는
[...s]또는Array.from(s) - 템플릿 리터럴 —
${}안에 식, 여러 줄 문자열 - 변환 —
String()/Number()/parseInt(),+값관용구 - 정규식 기본 — 메타 문자,
g플래그, 캡처 그룹 - 단순 검색,치환에는 정규식보다 메서드가 더 명확
다음 글(#7 모듈)에서는 시리즈 마지막으로 — 코드를 여러 파일로 나누는 ES Modules, import/export의 패턴들을 정리합니다.