Regex (정규표현식)
2025. 4. 10. 11:41
728x90
반응형

Regex ( Regular Expression )

  • 문자열에서 패턴을 검색하거나 대체할 때 사용되는 강력한 도구입니다. 
  • 수십 줄의 조건문을 정규식 한 줄로 표현 가능할 정도로 짧고 간결한 코드 구성에 용이합니다.
  • 문자 검색, 그룹 추출, 치환, 분리까지 전부 처리 가능합니다.
  • JavaScript, Python, Java, PHP 등 거의 모든 언어에서 동일한 문법으로 다양한 언어에서 사용 가능합니다.

기본 패턴

패턴 설명 예시
`.` 아무 문자 1개 (줄바꿈 제외) `/a.b/`은 "acb", "a#b" 등
`^` 문자열의 시작 `/^a/`는 "apple"과 매치, "banana"는 X
`$` 문자열의 끝 `/e$/`는 "apple"에 매치
`*` 0개 이상 반복 `/lo*/`는 "lo", "loo", "looo" 등
`+` 1개 이상 반복 `/lo+/`는 "lo", "loo", "looo" 등 (0개는 X)
`?` 0개 또는 1개 `/lo?/`는 "l", "lo"
`{n}` 정확히 n번 반복 `/a{3}/`는 "aaa"
`{n,}` n번 이상 반복 `/a{2,}/`는 "aa", "aaa", "aaaa" 등
`{n,m}` n~m번 반복 `/a{2,4}/`는 "aa", "aaa", "aaaa"
`[]` 문자 집합 `/[abc]/`는 "a", "b", "c" 중 하나
`[^]` 제외한 문자 집합 `/[^abc]/`는 "a", "b", "c" 아닌 것
`( )` 그룹화 `/(ab)+/`는 "ab", "abab" 등

 

특수 문자

문자 의미
`\d` 숫자 (0 ~ 9)
`\D` 숫자가 아닌 문자
`\w` 워드 문자 (알파벳, 숫자, 언더스코어)
`\W` 워드 문자가 아닌 것
`\s` 공백 문자 (스페이스, 탭 등)
`\S` 공백이 아닌 문자
`\b` 단어 경계
`\B` 단어 경계가 아님
`\` 이스케이프 문자

 

플래그 옵션

플래그 의미
`g` 전역 검색 (일치하는 모든 결과를 찾음)
`i` 대소문자 구분 없이 검색
`m` 여러 줄 검색: `^` `$`가 줄의 시작/끝에 작동
`s` `.`이 줄바꿈 문자(`\n`)도 포함하게 함
`u` 유니코드 지원 (💡 이모지나 특수문자용)
`y` lastIndex부터 정확하게 일치하는 위치에서만 검색 (고급 기능)

 

관련 메서드

매서드 설명
`test()` 패턴이 있는 지 확인합니다. ex) `/abc/.test('abcdef'); // true`
`exec()` 첫 매치 결과를 객체로 반환
`match()` 문자열에서 매치되는 부분 추출 ex) `'abc abc'.match(/a./g); // ["ab", "ab"]`
`replace()` 문자열 바꾸기 ex) `'abc123'.replace(/\d+/g, ''); // "abc"`
`split()` 정규식을 기준으로 문자열 나누기 ex) `'a,b;c.d'.split(/[;,.]/); // ["a", "b", "c", "d"]`

 

사용시 주의사항

  • 정규식 한 줄로 표현 가능할 정도로 짧고 간결한 코드 구성에 용이하나, 정규식이 복잡해질수록 읽기 어렵고 유지보수가 어렵습니다.
  • 에러가 나도 어떤 부분이 문제인지 찾기 힘들기 때문에, 디버깅의 난이도를 높힙니다.
  • 잘못된 정규식은 성능 문제를 일으킬 수 있습니다. ( ReDoS 공격 )
    • ReDoS 공격 : 공격자가 의도적으로 긴 입력을 넣으면 서버 성능이 마비될 수도 있음

알아두면 좋아요!!

1. 정규식 캐싱

  • JavaScript 엔진은 RegExp 객체로 만들면, 내부적으로 파싱해서 AST (추상 구문 트리)로 변환합니다. 그 후, 이를 NFA 기반의 엔진으로 컴파일합니다.
  • 이 컴파일된 정규식은 캐싱되어, 같은 정규식을 반복해서 쓰면 재사용합니다. 단, 생성자 방식 new RegExp()는 매번 새 객체를 생성하기 때문에 캐싱되지 않아요!
// 이건 캐시됨 (리터럴 방식)
const re1 = /abc/; 

// 이건 매번 새로 생성됨 (컴파일 비용↑)
const re2 = new RegExp('abc');

// ❌ 이렇게 하면 매번 새로 컴파일됨
function isValidEmail(email) {
  return new RegExp('^.+@.+$').test(email);
}

// ✅ 이렇게 하면 성능 훨씬 좋음
const emailRegex = /^.+@.+$/;
function isValidEmail(email) {
  return emailRegex.test(email);
}

2. ^ ,  $ 을 적극 활용하여 더 빠른 매치 판단을 내릴 수 있어요.

// ❌ 문자열 어디에 있어도 매치됨 (느림)
/\d{3}-\d{4}/

// ✅ 정확히 시작과 끝 지정 (더 빠름)
const regex = /^\d{3}-\d{4}$/;

3. RegExp.prototype.sticky 플래그 활용 (y)

const str = 'abc abc';
const re = /\w+/y;

re.lastIndex = 4;
console.log(re.exec(str)); // "abc" (index 4에서 정확히 시작해야 함)
// y 플래그는 정확한 위치에서만 매칭을 시도하므로, 불필요한 탐색을 줄일 수 있음
// 이는 큰 문자열을 처리할 때 유용합니다.
728x90
반응형

'javascript' 카테고리의 다른 글

알아두면 유용한 Regex 리스트와 match, matchAll  (0) 2025.04.16
Single Thread와 Javascript  (0) 2025.03.31
Scope Closure Currying  (0) 2025.03.30