Search
moon
sun

22.정규표현식

•
정규표현식이 무엇이고 왜 쓰는지 설명할 수 있다.
•
Oracle의 REGEXP_ 계열 함수 5종의 용도를 구분할 수 있다.
•
주요 메타문자(^ $ . [] \d {m,n} 등)의 의미를 안다.
•
이메일·전화번호·주민등록번호 같은 실제 패턴을 검증할 수 있다.

1) 정규표현식이란?

•
정규표현식(Regular Expression) 이란
특정한 규칙을 가진 문자열 집합을 표현하기 위한 형식 언어이다.
•
데이터 중 전화번호, 이메일, 주민등록번호, 우편번호 등
특정 패턴을 가진 문자열을 찾거나 검증할 때 사용된다.
•
Oracle에서는 REGEXP_ 계열 함수를 사용한다.
💡
LIKE 와 무엇이 다른가?LIKE 는 %(0자 이상)·_(1자) 두 가지 와일드카드만 씁니다. 정규식은 "숫자만", "3~4자리", "S 또는 A로 시작" 같은 훨씬 정교한 패턴을 표현할 수 있습니다.

2) Oracle 정규표현식 함수

함수명
설명
REGEXP_LIKE
LIKE문과 유사하며, 정규표현식으로 문자열을 검색
REGEXP_REPLACE
정규표현식에 일치하는 문자열을 다른 문자열로 치환
REGEXP_INSTR
정규표현식에 일치하는 문자열의 위치(Position) 반환
REGEXP_SUBSTR
정규표현식에 일치하는 부분 문자열(SubString) 추출
REGEXP_COUNT
정규표현식과 일치하는 문자열의 개수 반환

3) 정규표현식 메타문자

기호
의미
.
임의의 한 문자
?
앞 문자가 0개 또는 1개 존재
+
앞 문자가 1개 이상 존재
*
앞 문자가 0개 이상 존재
{m}
앞 문자가 정확히 m번 발생
{m,}
앞 문자가 최소 m번 이상 발생
{m,n}
앞 문자가 최소 m번 이상, 최대 n번 이하 발생
[abc]
a,b,c 중 임의의 한 문자와 일치
[^abc]
a,b,c 이외의 문자와 일치
^
문자열 시작
$
문자열 끝
\d
숫자(0~9)
\w
알파벳, 숫자, 밑줄(_)
\s
공백문자
[:alpha:]
알파벳 문자
[:digit:]
숫자
[:upper:]
대문자
[:lower:]
소문자
[:alnum:]
알파벳 또는 숫자
[:space:]
공백 문자
[:punct:]
특수 문자
⚠️ 가장 헷갈리는 3가지
•
[^abc] 의 ^ 는 "제외" (대괄호 안), ^abc 의 ^ 는 "시작" (대괄호 밖) — 위치로 구분!
•
(0개 이상) vs + (1개 이상) — + 는 최소 1개는 있어야 함
•
[:alpha:] 같은 POSIX 클래스는 대괄호로 한 번 더 감싸 [[:alpha:]] 로 써야 함

4) REGEXP_LIKE 예시

-- 숫자가 포함된 데이터 찾기 SELECT SAL FROM EMP WHERE REGEXP_LIKE(SAL, '[0-9]'); -- SAL(급여)은 모두 숫자이므로 EMP 전체(14건)가 조회된다
SQL
복사
-- 영문자와 숫자가 함께 있는 데이터 찾기 SELECT DATA FROM ( SELECT 'A123' AS DATA FROM DUAL UNION ALL SELECT 'ABC' AS DATA FROM DUAL ) A WHERE REGEXP_LIKE(DATA, '[0-9]') AND REGEXP_LIKE(DATA, '[A-Z]'); -- 영문자와 숫자가 모두 포함된 데이터 조회 -- => 결과: A123
SQL
복사
✅ 예제 확인 — 왜 A123 만 나오는가?
DATA
[0-9](숫자 포함?)
[A-Z](영문 포함?)
두 조건 AND
A123
✅ (1,2,3)
✅ (A)
✅ 조회됨
ABC
❌ (숫자 없음)
✅ (A,B,C)
❌ 제외
-- 영문자가 포함된 데이터 SELECT DATA FROM ( SELECT 'A123' AS DATA FROM DUAL UNION ALL SELECT 'ABC' AS DATA FROM DUAL ) A WHERE REGEXP_LIKE(DATA, '[a-zA-Z]'); -- 영문자가 포함된 데이터 조회 -- => 결과: A123, ABC
SQL
복사
✅ 예제 확인 — [a-zA-Z] 는 대소문자 영문 전부. A123(A 포함)·ABC(전부 영문) 둘 다 영문자가 있어 2건 모두 조회됩니다.

5) 이메일 패턴 찾기

-- 이메일 주소 형식에 맞는 데이터 찾기 SELECT DATA FROM ( SELECT 'limhojin123@naver.com' AS DATA FROM DUAL UNION ALL SELECT '828' AS DATA FROM DUAL ) A WHERE REGEXP_LIKE(DATA, '[[:alnum:]]+@[[:alnum:]]+\.[[:alpha:]]{3,4}'); -- [[:alnum:]]+ → 알파벳·숫자 1개 이상 -- @ → @ 기호 포함 -- \. => 점(.) 문자 -- {3,4} => 도메인 확장자 길이(3~4)
SQL
복사
✅ 예제 확인 — 패턴을 조각내서 읽기
패턴 조각
의미
limhojin123@naver.com
[[:alnum:]]+
영숫자 1개 이상
limhojin123 ✅
@
@ 기호
@ ✅
[[:alnum:]]+
영숫자 1개 이상
naver ✅
\.
점 문자
. ✅
[[:alpha:]]{3,4}
영문 3~4자
com ✅
→ limhojin123@naver.com 은 통과, 828 은 @ 가 없어 제외 → 결과: limhojin123@naver.com
⚠️ \. 의 역슬래시가 핵심입니다. 그냥 . 은 "임의의 한 문자"라 아무 글자에나 걸립니다. 점(.) 자체를 찾으려면 앞에 \ 를 붙여 \. 로 써야 합니다.

6) 전화번호 패턴 찾기

-- 전화번호 정규표현식 예시 SELECT * FROM ( SELECT '010-9821-9999' AS DATA FROM DUAL UNION ALL SELECT '01a-9811-b99' AS DATA FROM DUAL ) A WHERE REGEXP_LIKE(DATA, '^01[016-9]-\d{3,4}-\d{4}$'); -- ^01[016-9] : 010, 011, 016~019로 시작 -- \d{3,4} : 숫자 3~4자리 -- \d{4} : 숫자 4자리 -- $ : 문자열 끝 -- 결과 => 010-9821-9999
SQL
복사
✅ 예제 확인 — 두 데이터 비교
DATA
판정
이유
010-9821-9999
✅ 통과
010 시작 + 숫자 4자리 + 숫자 4자리
01a-9811-b99
❌ 제외
01a 의 a(숫자 아님), b99 의 b(숫자 아님)
⭐ ^ (시작)과 $ (끝)를 양쪽에 두면 "전체가 정확히 이 패턴" 이라는 뜻입니다. ^ $ 가 없으면 "이 패턴을 포함만 해도" 통과되어 검증이 느슨해집니다.

7) 주민등록번호 패턴 찾기

SELECT * FROM ( SELECT '788887-1001000' AS DATA FROM DUAL ) A WHERE REGEXP_LIKE(DATA, '^\d{6}-\d{7}$'); -- 주민등록번호 형식 검색 -- 앞 6자리 숫자 + - + 뒤 7자리 숫자
SQL
복사
✅ 예제 확인
패턴 조각
의미
788887-1001000
^\d{6}
시작, 숫자 6자리
788887 ✅
-
하이픈
- ✅
\d{7}$
숫자 7자리, 끝
1001000 ✅
→ 형식이 맞아 조회됨. 만약 78888-1001000(앞 5자리)이면 {6} 불만족으로 제외됩니다.

8) REGEXP_SUBSTR — 문자열 추출

SELECT REGEXP_SUBSTR('AAA, BBB, CCC, DDD', '[^, ]+', 1, 1) AS DATA1, REGEXP_SUBSTR('AAA, BBB, CCC, DDD', '[^, ]+', 1, 2) AS DATA2, REGEXP_SUBSTR('AAA, BBB, CCC, DDD', '[^, ]+', 1, 3) AS DATA3, REGEXP_SUBSTR('AAA, BBB, CCC, DDD', '[^, ]+', 1, 4) AS DATA4 FROM DUAL; -- 결과 => -- DATA1 = AAA, DATA2 = BBB, DATA3 = CCC, DATA4 = DDD -- [^, ]+ → 쉼표(,)와 공백을 제외한 문자열 추출
SQL
복사
✅ 예제 확인 — 인자의 의미
REGEXP_SUBSTR(대상, 패턴, 시작위치, 몇번째)
마지막 인자
의미
결과
1, 1
1번 위치부터 1번째 일치
AAA
1, 2
1번 위치부터 2번째 일치
BBB
1, 3
3번째
CCC
1, 4
4번째
DDD
⭐ [^, ]+ = "쉼표(,)도 공백( )도 아닌 문자가 1개 이상" → 구분자 사이의 값만 뽑아냅니다. SUBSTR 은 위치로만 잘랐지만, REGEXP_SUBSTR 은 패턴으로 잘라냅니다.
-- 날짜 분리하기 SELECT REGEXP_SUBSTR('2024-08-22', '[^-/.]+', 1, 1) AS YEAR, REGEXP_SUBSTR('2024/08/22', '[^-/.]+', 1, 2) AS MONTH, REGEXP_SUBSTR('2024.08.22', '[^-/.]+', 1, 3) AS DAY FROM DUAL; -- 결과 => YEAR=2024, MONTH=08, DAY=22
SQL
복사
✅ 예제 확인 — [^-/.]+ = "하이픈·슬래시·점이 아닌 문자". 구분자가 - / . 무엇이든 상관없이 값만 뽑아냅니다. → 1번째 2024, 2번째 08, 3번째 22.

9) REGEXP_INSTR — 문자열 위치 찾기

SELECT ENAME, REGEXP_INSTR(ENAME, 'LE') AS RESULT FROM EMP; -- ‘LE’ 문자열이 등장하는 위치 조회
SQL
복사
✅ 예제 확인 — 일부 사원의 결과
ENAME
LE 위치
설명
ALLEN
3
ALLEN → 3번째부터
MILLER
4
MILLER → 4번째부터
SMITH
0
LE 없음 → 0 (09강 INSTR 과 동일하게 못 찾으면 0)
-- 한글 문자 위치 찾기 SELECT REGEXP_INSTR('abc@ABC@123안녕HH', '[가-힣]') AS POS FROM DUAL; --결과: 12
SQL
복사
✅ 예제 확인 — [가-힣] = 모든 한글 음절. abc@ABC@123안녕HH 에서 첫 한글 안 의 위치를 세면 (a·b·c·@·A·B·C·@·1·2·3 = 11자) 그다음 12번째입니다.

10) 핵심 요약

함수
주요 기능
REGEXP_LIKE
정규표현식 검색
REGEXP_SUBSTR
일치하는 부분 문자열 추출
REGEXP_INSTR
일치 문자열 위치 반환
REGEXP_REPLACE
일치 문자열 치환
REGEXP_COUNT
일치 횟수 반환

11) REGEXP_REPLACE · REGEXP_COUNT 예제 (보충)

-- REGEXP_REPLACE : 전화번호의 숫자를 모두 * 로 마스킹 SELECT REGEXP_REPLACE('010-1234-5678', '[0-9]', '*') AS 마스킹 FROM DUAL; -- 결과 => ***-****-**** -- [0-9] (모든 숫자) 를 * 로 치환. 하이픈은 숫자가 아니라 그대로 남는다.
SQL
복사
-- REGEXP_COUNT : 특정 패턴이 몇 번 나오는지 SELECT REGEXP_COUNT('AAA, BBB, CCC, DDD', '[^, ]+') AS 단어수 FROM DUAL; -- 결과 => 4 (쉼표·공백으로 구분된 단어가 4개)
SQL
복사
✅ 예제 확인 — REGEXP_COUNT 는 패턴과 일치하는 부분이 몇 번 나오는지 셉니다. 위에서는 구분자를 제외한 단어(AAA BBB CCC DDD)가 4개이므로 4.

출제 포인트 한눈에 정리

#
꼭 외울 것
핵심
1
정규식 함수 5종
LIKE SUBSTR INSTR REPLACE COUNT 의 REGEXP_ 버전
2
REGEXP_LIKE
조건절에서 패턴 검색 (LIKE 강화판)
3
^
문자열 시작 (대괄호 밖)
4
$
문자열 끝
5
[^abc]
abc 제외 (대괄호 안의 ^) ⭐
6
.
임의의 1자
7
\.
점(.) 문자 자체 ⭐
8
* vs +
0개 이상 vs 1개 이상
9
\d
숫자 ([0-9] 와 동일)
10
{m,n}
m~n번 반복
11
POSIX 클래스
[[:alpha:]] 처럼 이중 대괄호
12
REGEXP_INSTR 못 찾으면
0 (09강 INSTR 과 동일)
13
REGEXP_SUBSTR 인자
(대상, 패턴, 시작위치, 몇번째)
14
^~$ 전체 감싸기
"정확히 이 형식" 검증

확인 문제

Q1. 정규식에서 [^abc] 와 ^abc 의 ^ 는 각각 무슨 의미인가?
정답 보기
Q2. 이메일 패턴 [[:alnum:]]+@[[:alnum:]]+\.[[:alpha:]]{3,4} 에서 \. 을 그냥 . 으로 쓰면 어떻게 되는가?
정답 보기
Q3. 다음 중 REGEXP_LIKE(DATA, '^\d{6}-\d{7}$') 를 통과하는 데이터는? ① 78888-1001000 ② 788887-1001000 ③ 788887-100100a ④ 7888871001000
정답 보기
Q4. REGEXP_SUBSTR('AAA, BBB, CCC', '[^, ]+', 1, 2) 의 결과는?
정답 보기
Q5. SMITH 에 대해 REGEXP_INSTR('SMITH', 'LE') 의 결과는?
정답 보기
Q6. REGEXP_REPLACE('A1B2C3', '[0-9]', '#') 의 결과는?
정답 보기