# 정규표현식 (RegExp) 문법 정리

데이터를 다룰 때, 잘하면 잘할수록 역량과 성과가 오르는 기술 중 하나가 정규표현식 (Regular Expression)이다.

정규표현식을 잘 알면 특정한 조건의 문자를 검색하거나 추출, 치환하는 과정을 매우 간편하게 처리 할 수 있다.

하지만 정규표현식은 숙달되어 있지 않다면 보자마자 한 눈에 파악하기 쉽지 않고 잘 헷갈리기 때문에 자주 사용되는 문법을 정리하여 익숙해지기 위해 포스팅을 시작한다.

---

## RegExp

### 반복/선택 관련 기호

* `?`: 바로 앞 문자가 **0개 또는 1개** 있음을 의미  
    예: `do?`는 `'d'`나 `'do'`에 매칭됨.
    
* `.`: 임의의 문자 한 글자를 의미 (SQL의 `LIKE '_'`와 유사)  
    예: `.d`는 `'ad'`, `'bd'`, `'1d'` 등 어떤 문자 + 'd'에 매칭
    
* `...`: 점을 3개 쓰면 **아무 글자 3개**를 의미  
    예: `^...$`는 정확히 3글자인 문자열을 의미
    
* `+`: 바로 앞 문자가 **1회 이상** 반복  
    예: `a+`는 `'a'`, `'aa'`, `'aaa'` 등 'a'가 한 번 이상 반복되는 문자열
    
* `*`: 바로 앞 문자가 **0회 이상** 반복  
    예: `a*`는 '', 'a', 'aa', 'aaa' 모두 매칭
    

### **문자열 위치 지정**

* `^`: 문자열의 **시작** 부분을 의미  
    예: `^c`는 'c'로 시작하는 문자열
    
* `$`: 문자열의 **끝** 부분을 의미  
    예: `y$`는 'y'로 끝나는 문자열
    

### **그룹화 및 범위 지정**

* `()`: 괄호 안의 패턴을 하나의 그룹으로 묶음  
    예: `(ha)+`는 'ha', 'haha', 'hahaha' 등 'ha' 반복되는 패턴
    
* `[]`: 대괄호 안에 문자 범위를 지정
    
* `[abc]`: 'a', 'b', 'c' 중 하나에 매칭
    
* `[0-9]`: 0부터 9까지 숫자 하나에 매칭 (숫자 한 글자)
    
* `[^0-9]`: 숫자가 아닌 문자 하나에 매칭 ('^'가 대괄호 안에서 사용되면 부정)
    

### **반복 횟수 지정**

* `{n}`: 정확히 n번 반복  
    예: `[0-9]{2}`는 숫자 2개 연속 (예: '12', '99')
    
* `{m,n}`: m번 이상 n번 이하 반복  
    예: `[a-z]{2,4}`는 알파벳 소문자 2~4글자
    

### **기타**

`REGEXP 'do'`는 `LIKE '%do%'`와 유사하게 'do'가 들어있는 문자열을 찾는다.

`REGEXP '^do'`는 'do'로 시작하는 문자열(`LIKE 'do%'`)을 의미한다.

`REGEXP 'do$'`는 'do'로 끝나는 문자열(`LIKE '%do'`)을 의미한다.

`\s`는 공백 문자를 의미. `\d`는 숫자(0-9)를 의미 (일부 정규식 엔진에서 지원).

---

## 예제 (MySQL)

1. `select * from test where eng regexp 'do?';`
    
    * `'do?'`는 'd' 다음에 'o'가 0개 또는 1개 있을 수 있음을 의미
        
    * 매칭 대상: `'d'` 혹은 `'do'` 포함한 문자열
        
2. `select * from test where name regexp '^..$';`
    
    * `^..$`는 문자열 시작(`^`)부터 정확히 2글자(`..`), 그리고 바로 끝(`$`)
        
    * 즉, 정확히 2글자로 된 `name` 값을 찾는다.
        
3. `select * from test where eng regexp '^I';`
    
    * `^I`는 'I'로 시작하는 문자열
        
    * `'I...'`와 같이 시작 문자가 'I'인 문자열을 찾는다.
        
4. `select * from test where eng regexp '^I\'';`
    
    * `'^I\''`는 'I''로 시작하는 문자열 (`I'`가 문자열의 시작 부분)
        
    * 예: `"I'm"`, `"I'abc"` 등이 매칭 가능 (특수문자 `'`를 예제처럼 이스케이프 \\ 하거나 문자열 리터럴 처리를 정확히 해야 함).
        
5. `SELECT * FROM test WHERE col1 REGEXP '^[0-9]+$';`
    
    * `^[0-9]+$`: 시작부터 끝까지 숫자(`0-9`)가 1개 이상 반복되는 문자열
        
    * 즉, 순수 숫자로만 이루어진 문자열을 찾는다.
        
6. `SELECT * FROM test WHERE col1 REGEXP '^[[:digit:]]+$';`
    
    * `[:digit:]`도 숫자 클래스
        
    * `^[[:digit:]]+$`는 위와 동일하게 순수 숫자만으로 구성된 문자열.
        
7. `SELECT * FROM test WHERE col1 NOT REGEXP '^[0-9]+$';`
    
    * NOT REGEXP를 사용해 숫자로만 된 문자열이 아닌 것들을 찾는다.
        
8. `SELECT * FROM test WHERE length(col1) > 0 and col1 NOT REGEXP '^[0-9]+$';`
    
    * 길이가 0보다 크고, 숫자만으로 이루어지지 않은 문자열을 찾는다.
        
    * 즉, 빈 문자열이 아니며 숫자만도 아닌 문자열을 필터링.
        
9. `SELECT * FROM test WHERE col1 REGEXP '[0-9]+';`
    
    * `[0-9]+`는 최소 한 글자 이상의 숫자를 포함하는 문자열을 의미.
        
    * 숫자와 문자가 섞여 있어도 숫자가 들어있기만 하면 매칭.
        

---

## DBMS 별 정규표현식 사용법

SQL에서 정규표현식을 사용하는 방식은 데이터베이스 시스템에 따라 다르다. 가장 일반적으로 알려진 사용법은 `regexp` 접두어를 붙이는 것이지만, 각각의 DBMS 마다 전용 함수나 연산자가 있기 때문에 함께 알아두자.

1. MySQL / MariaDB
    
    `REGEXP` 또는 `RLIKE`
    
    ```sql
    SELECT * FROM table_name
    WHERE column_name REGEXP ' ';
    ```
    

REGEXP ‘ ‘ 안에 정규표현식을 넣으면 해당 패턴과 일치하는 행을 반환한다.

2. PostgreSQL
    
    `~` 또는 `~*` 연산자를 사용하며, 대소문자 구분 여부에 따라 다르다.
    
    ```sql
    SELECT * FROM table_name
    WHERE column_name ~ 'pattern';    -- 대소문자 구분
    WHERE column_name ~* 'pattern';   -- 대소문자 구분 없음
    ```
    

3. BigQuery
    
    `REGEXP_CONTAINS`, `REGEXP_EXTRACT`, `REGEXP_REPLACE` 등 함수를 활용
    
    ```sql
    SELECT * FROM table_name
    WHERE REGEXP_CONTAINS(column_name, r'pattern');
    ```
    
    여기서 `r'pattern'`은 BigQuery SQL 문법에서 정규표현식 패턴을 위한 String literal이며, Python의 Raw String과 혼동하지 않아야 한다.
    
    > **💡 Python의 Raw String이란?**
    > 
    > 문자열 내에서 이스케이프 시퀀스를 특별하게 처리하지 않고, 백슬래시 \\ 를 있는 그대로 문자로 인식하는 문자열 표기 방식이다. `\n`을 개행으로 해석하지 않고 두 문자의 조합 `”\”`와 `”n”`로 유지하는 것이 특징이다.
    > 
    > 문자열 앞에 `r` 또는 `R`을 붙여 raw string을 만든다.
    > 
    > ```python
    > normal_str = "Hello\nWorld"  # 여기서 \n은 줄바꿈 문자로 해석
    > raw_str = r"Hello\nWorld"     # 여기서 \n은 줄바꿈으로 해석되지 않고 "\n" 그대로 유지
    > ```
    
4. Oracle
    
    `REGEXP_LIKE` 함수를 사용
    
    ```sql
    SELECT * FROM table_name
    WHERE REGEXP_LIKE(column_name, 'pattern');
    ```
