데이터를 다룰 때, 잘하면 잘할수록 역량과 성과가 오르는 기술 중 하나가 정규표현식 (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)
select * from test where eng regexp 'do?';
'do?'
는 'd' 다음에 'o'가 0개 또는 1개 있을 수 있음을 의미매칭 대상:
'd'
혹은'do'
포함한 문자열
select * from test where name regexp '^..$';
^..$
는 문자열 시작(^
)부터 정확히 2글자(..
), 그리고 바로 끝($
)즉, 정확히 2글자로 된
name
값을 찾는다.
select * from test where eng regexp '^I';
^I
는 'I'로 시작하는 문자열'I...'
와 같이 시작 문자가 'I'인 문자열을 찾는다.
select * from test where eng regexp '^I\'';
'^I\''
는 'I''로 시작하는 문자열 (I'
가 문자열의 시작 부분)예:
"I'm"
,"I'abc"
등이 매칭 가능 (특수문자'
를 예제처럼 이스케이프 \ 하거나 문자열 리터럴 처리를 정확히 해야 함).
SELECT * FROM test WHERE col1 REGEXP '^[0-9]+$';
^[0-9]+$
: 시작부터 끝까지 숫자(0-9
)가 1개 이상 반복되는 문자열즉, 순수 숫자로만 이루어진 문자열을 찾는다.
SELECT * FROM test WHERE col1 REGEXP '^[[:digit:]]+$';
[:digit:]
도 숫자 클래스^[[:digit:]]+$
는 위와 동일하게 순수 숫자만으로 구성된 문자열.
SELECT * FROM test WHERE col1 NOT REGEXP '^[0-9]+$';
- NOT REGEXP를 사용해 숫자로만 된 문자열이 아닌 것들을 찾는다.
SELECT * FROM test WHERE length(col1) > 0 and col1 NOT REGEXP '^[0-9]+$';
길이가 0보다 크고, 숫자만으로 이루어지지 않은 문자열을 찾는다.
즉, 빈 문자열이 아니며 숫자만도 아닌 문자열을 필터링.
SELECT * FROM test WHERE col1 REGEXP '[0-9]+';
[0-9]+
는 최소 한 글자 이상의 숫자를 포함하는 문자열을 의미.숫자와 문자가 섞여 있어도 숫자가 들어있기만 하면 매칭.
DBMS 별 정규표현식 사용법
SQL에서 정규표현식을 사용하는 방식은 데이터베이스 시스템에 따라 다르다. 가장 일반적으로 알려진 사용법은 regexp
접두어를 붙이는 것이지만, 각각의 DBMS 마다 전용 함수나 연산자가 있기 때문에 함께 알아두자.
MySQL / MariaDB
REGEXP
또는RLIKE
SELECT * FROM table_name WHERE column_name REGEXP ' ';
REGEXP ‘ ‘ 안에 정규표현식을 넣으면 해당 패턴과 일치하는 행을 반환한다.
PostgreSQL
~
또는~*
연산자를 사용하며, 대소문자 구분 여부에 따라 다르다.SELECT * FROM table_name WHERE column_name ~ 'pattern'; -- 대소문자 구분 WHERE column_name ~* 'pattern'; -- 대소문자 구분 없음
BigQuery
REGEXP_CONTAINS
,REGEXP_EXTRACT
,REGEXP_REPLACE
등 함수를 활용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을 만든다.normal_str = "Hello\nWorld" # 여기서 \n은 줄바꿈 문자로 해석 raw_str = r"Hello\nWorld" # 여기서 \n은 줄바꿈으로 해석되지 않고 "\n" 그대로 유지
Oracle
REGEXP_LIKE
함수를 사용SELECT * FROM table_name WHERE REGEXP_LIKE(column_name, 'pattern');