자바스크립트에서 정규표현식 제대로 이해하기
date
Jan 12, 2025
slug
regex-basic-guide-js
author
status
Public
tags
React
summary
정규표현식은 문자열에서 특정 패턴을 찾고 대체하며 추출할 수 있는 강력한 도구입니다. 이 글에서는 자바스크립트 중심으로 정규표현식의 주요 메타문자, 반복 패턴, 전방/후방탐색, 탐욕적 매칭과 비탐욕적 매칭까지 다양한 실전 예제와 함께 핵심 개념을 정리했습니다.
type
Post
thumbnail
category
💻 Frontend
updatedAt
May 25, 2025 10:01 AM
1. 정규표현식이란?
- 문자열에서 특정한 패턴을 찾거나, 대체하거나, 추출하는 데 사용되는 문자 조합입니다.
프로젝트를 진행하다 보면 정규표현식을 사용할 일이 많습니다. 이를 제대로 공부하고 활용하기 위해, 정규표현식의 사용법과 주요 기능을 정리해보고자 합니다.
2. 정규표현식의 주요 메타문자
문자 단위 메타문자
메타문자 | 의미 | 예제 | 매칭 예시 |
. | 임의의 한 문자 | a.c | abc, a1c, a#c |
\d | 숫자 (0-9) | \d+ | "123", "42" |
\D | 숫자가 아닌 문자 | \D+ | "abc", "#@" |
\w | 문자, 숫자, 밑줄 | \w+ | "hello", "world_123" |
\W | 문자, 숫자가 아닌 문자 | \W+ | "@#!", " " |
\s | 공백 문자 | \s+ | " ", "\t" |
\S | 공백이 아닌 문자 | \S+ | "hello", "123" |
const str = "Hello 123!"; console.log(str.match(/\d+/g)); // ["123"] (숫자만 매칭) console.log(str.match(/\D+/g)); // ["Hello "] (숫자가 아닌 문자만 매칭) console.log(str.match(/\w+/g)); // ["Hello", "123"] (단어 문자 매칭) console.log(str.match(/\W+/g)); // [" "] (단어 문자가 아닌 것 매칭) console.log(str.match(/\s+/g)); // [" "] (공백 문자 매칭) console.log(str.match(/\S+/g)); // ["Hello", "123!"] (공백이 아닌 문자 매칭)
경계 관련 메타문자
메타문자 | 의미 | 예제 | 매칭 예시 |
^ | 문자열의 시작 | ^Hello | "Hello world" |
$ | 문자열의 끝 | end$ | "the end" |
\b | 단어의 경계 | \bword\b | "word", "word!" |
\B | 단어 경계가 아닌 곳 | \Bword\B | "swordfish" |
const str2 = "The end is near."; console.log(str2.match(/^The/)); // ["The"] (문자열의 시작에서 "The" 매칭) console.log(str2.match(/near\.$/)); // ["near."] (문자열 끝에서 "near." 매칭) console.log(str2.match(/\bend\b/g)); // ["end"] (단어 경계에 있는 "end" 매칭) console.log(str2.match(/\Bend\B/g)); // null (경계 내부에서 "end" 매칭 불가)
반복 관련 메타문자
메타문자 | 의미 | 예제 | 매칭 예시 |
* | 0개 이상 반복 | ab*c | "ac", "abc", "abbc" |
+ | 1개 이상 반복 | ab+c | "abc", "abbc" |
? | 0개 또는 1개 | colou?r | "color", "colour" |
{n} | 정확히 n개 반복 | a{3} | "aaa" |
{n,} | n개 이상 반복 | a{2,} | "aa", "aaa", "aaaa" |
{n,m} | n개 이상 m개 이하 반복 | a{2,4} | "aa", "aaa", "aaaa" |
const str3 = "aaab aac ab aabb"; console.log(str3.match(/a*b/g)); // ["aaab", "ab", "aabb"] (0개 이상 "a" 포함) console.log(str3.match(/a+b/g)); // ["aaab", "ab", "aabb"] (1개 이상 "a" 포함) console.log(str3.match(/a?b/g)); // ["ab", "ab", "b"] ("a"가 0개 또는 1개 포함) console.log(str3.match(/a{2,}/g)); // ["aaa", "aa", "aabb"] (2개 이상 "a" 포함) console.log(str3.match(/a{2,3}/g)); // ["aaa", "aa"] (2~3개 "a" 포함)
그룹 및 선택 관련 메타문자
메타문자 | 의미 | 예제 | 매칭 예시 |
| | OR | apple|banana | "apple", "banana" |
() | 그룹 | (abc)+ | "abc", "abcabc" |
(?:...) | 비포획 그룹 | (?:abc)+ | "abc", "abcabc" |
const str4 = "apple banana grape"; console.log(str4.match(/apple|banana/g)); // ["apple", "banana"] ("apple" 또는 "banana" 매칭) console.log(str4.match(/(ba|gra)pe/g)); // ["grape"] ("ba" 또는 "gra"로 시작하는 "pe" 매칭) console.log(str4.match(/(?:apple|banana)/g)); // ["apple", "banana"] (비포획 그룹)
탐욕적 vs. 비탐욕적 메타문자
메타문자 | 의미 | 예제 | 매칭 방식 |
* | 0개 이상 탐욕적 | a.*b | "axbxbxb" → "axbxbxb" |
*? | 0개 이상 비탐욕적 | a.*?b | "axbxbxb" → "axb" |
+ | 1개 이상 탐욕적 | a.+b | "axbxbxb" → "axbxbxb" |
+? | 1개 이상 비탐욕적 | a.+?b | "axbxbxb" → "axb" |
{n,} | n개 이상 탐욕적 | a{2,}b | "aaab" → "aaab" |
{n,}? | n개 이상 비탐욕적 | a{2,}?b | "aaab" → "aab" |
const str5 = "axbxbxb"; console.log(str5.match(/a.*b/)); // ["axbxbxb"] (탐욕적 매칭) console.log(str5.match(/a.*?b/)); // ["axb"] (비탐욕적 매칭) console.log(str5.match(/a.+b/)); // ["axbxbxb"] (1개 이상 탐욕적) console.log(str5.match(/a.+?b/)); // ["axb"] (1개 이상 비탐욕적)
문자 클래스 관련 메타문자
메타문자 | 의미 | 예제 | 매칭 예시 |
[...] | 문자 집합 (하나만 매칭) | [aeiou] | "apple" → "a", "e" |
[^...] | 제외된 문자 집합 | [^0-9] | "hi123!" → "hi", "!" |
[a-z] | 소문자 a부터 z까지 | [a-z]+ | "Hello123" → "ello" |
[A-Z] | 대문자 A부터 Z까지 | [A-Z]+ | "PyTHon" → "P", "T", "H" |
[0-9] | 숫자 0부터 9까지 | [0-9]+ | "abc123xyz" → "123" |
const str6 = "Hello 123!"; console.log(str6.match(/[aeiou]/g)); // ["e", "o"] (모음 매칭) console.log(str6.match(/[^0-9]+/g)); // ["Hello ", "!"] (숫자 제외) console.log(str6.match(/[a-z]+/g)); // ["ello"] (소문자만 매칭) console.log(str6.match(/[A-Z]+/g)); // ["H"] (대문자만 매칭) console.log(str6.match(/[0-9]+/g)); // ["123"] (숫자만 매칭)
후방탐색과 전방탐색 메타문자
메타문자 | 의미 | 예제 | 매칭 예시 |
(?=...) | 긍정형 전방탐색 | foo(?=bar) | "foobar" |
(?!...) | 부정형 전방탐색 | foo(?!bar) | "foo123" |
(?<=...) | 긍정형 후방탐색 | (?<=\$)\d+ | "$100" → "100" |
(?<!...) | 부정형 후방탐색 | (?<!\$)\d+ | "100" |
const str7 = "$100 200"; console.log(str7.match(/(?<=\$)\d+/g)); // ["100"] ($ 뒤에 오는 숫자) console.log(str7.match(/(?<!\$)\d+/g)); // ["200"] ($ 없는 숫자) console.log(str7.match(/foo(?=bar)/g)); // ["foo"] (뒤에 "bar"가 있는 "foo"만 매칭) console.log(str7.match(/foo(?!bar)/g)); // ["foo"] (뒤에 "bar"가 없는 "foo"만 매칭)