SQLD 정규표현식

AnalytiCode·2025년 5월 29일

진짜 미루고 미루고 미루다.. 이거라도 맞춰야 합격 가능성이 올라갈 것 같아서...

POSIX 연산자

  • .(dot) :임의의 한 문자 (newline 제외)
    ex) a.b : acb, a-b, a1b …
  • |(or): 대체 문자를 구분
  • \(backslash) : 다음 문자(특수문자)를 일반 문자로 취급

REGEXP_SUBSTR

문자열에서 일치하는 패턴 반환

REGEXP_SUBSTR(문자열, 패턴 , 시작위치 , 찾는 번째 , match_parameter)

  • SELECT REGEXP_SUBSTR('ab12cd34ef', '\d+', 1, 1) AS result FROM DUAL;
    패턴 : 숫자 하나 이상
    찾는 번째 : 첫번째 숫자 그룹 추출
    결과: 12

  • SELECT REGEXP_SUBSTR('ab12cd34ef', '\d+', 1, 2) AS result FROM DUAL;
    찾는 번째 : 두번째 숫자 그룹 추출
    결과: 34

  • SELECT REGEXP_SUBSTR('acb a1b a_b a--b axxb', 'a.b', 1, 1) AS result FROM DUAL;
    패턴 : a.b
    찾는 번째 : 첫번째 숫자 그룹 추출
    결과: acb

  • REGEXP_SUBSTR ('a|b', 'a|b' )
    결과 : a (하나만 나옴)

  • SELECT REGEXP_SUBSTR('I love dog and cat', 'cat|dog', 1, 1) AS result FROM DUAL;
    패턴: cat or dog 둘 중에 하나
    결과: dog

  • SELECT REGEXP_SUBSTR('abc.com def.co.kr', '\.', 1, 1) AS result FROM DUAL;
    패턴 : 마침표 자체 의미
    결과 : .

REPLACE

  • REPLACE(문자열, 찾을_문자, 바꿀_문자)

  • REGEXP_REPLACE(문자열, 정규표현식, 바꿀_문자, 시작위치, nth-출현, match_parameter)
    nth-출현: 몇번째 매치만 바꾸는 것도 가능

  • SELECT REGEXP_REPLACE('ab12cd34ef', '\d+', '') AS result FROM DUAL;
    패턴 : 숫자 하나 이상
    결과 : 숫자를 모두 빈 문자열로 바꿈 => abcdef

  • SELECT REGEXP_REPLACE('cat or dog', 'cat|dog', 'animal') AS result FROM DUAL;
    결과 : animal or animal

INSTR

문자열에서 특정 문자의 위치(index)를 알려줌

  • INSTR(문자열, 찾을문자, 시작위치, 몇번째등장)

  • REGEXP_INSTR(문자열, 정규표현식, 시작위치, nth-출현, return_option, match_parameter)
    return_option = 0이면 패턴의 시작위치
    return_option = 1이면 패턴의 끝 다음 위치

  • SELECT REGEXP_INSTR('ab12cd34ef', '\d+', 1, 2, 0) AS result FROM DUAL;
    2번째 등장하는 숫자 그룹의 위치 => 7

anchor(앵커) 연산자

검색패턴의 시작과 끝 지정

  • ^ : 문자열의 시작
  1. SELECT REGEXP_SUBSTR ('ab' || CHR(10) || 'cd', '^.', 1, 1)
    'ab' || 줄바꿈 || 'cd' 라는 문자열에서 시작 한글자를 찾아라
    => a

  2. SELECT REGEXP_SUBSTR('ab' || CHR(10) || 'cd', '^.', 1, 2)
    패턴이 ^.로 문자열 시작에서만 매치(2번째 등장 자체가 없음)
    => NULL

  • $ : 문자열의 끝

  • expr : 표현식을 하나로 취급

  1. select REGEXP_SUBSTR ('ababc', '(ab)+c')
    패턴 : 'ab'가 한번 이상 반복된 다음 c (+: 하나 이상 반복)
    => 'ababc'
  2. select REGEXP_SUBSTR ('ababc', 'ab+c')
    패턴: b가 한번 이상 반복된 다음 c
    => abc
  • || : 문자열을 붙이는 연산자
    'a' || 'b' → 'ab'

수량자 연산자

연산자의미예시 (a 기준)설명
?0회 또는 1회 일치a?'', 'a' 에 매치됨
*0회 이상 반복a*'', 'a', 'aa'...
+1회 이상 반복a+'a', 'aa', 'aaa'...
{m}정확히 m회 일치a{3}'aaa'
{m,}최소 m회 이상 일치a{2,}'aa', 'aaa', 'aaaa'...
{,m}최대 m회 이하 일치 (비권장)a{,3}'', 'a', 'aa', 'aaa'
{m,n}m회 이상 n회 이하 일치a{2,4}'aa', 'aaa', 'aaaa'

역참조 연산자

  • \n : n번째 서브 표현식과 일치, n은 1에서 9사이의 정수
    정규표현식에서 ()로 감싸면 그 안의 매치된 문자열을 기억.
    ()를 \n을 사용해서 참조가능
SELECT REGEXP_SUBSTR ('abxab' , '(ab|cd)x\1') AS C1 -- abxab, cdxcd
     , REGEXP_SUBSTR ('cdxcd' , '(ab|cd)x\1') AS C2 -- cdxcd
     , REGEXP_SUBSTR ('abxef' , '(ab|cd)x\1') AS C3
     , REGEXP_SUBSTR ('ababab', '(.*)\1+'   ) AS C4 -- ab 3번, ababab
     , REGEXP_SUBSTR ('abcabc', '(.*)\1+'   ) AS C5 -- abcabc
     , REGEXP_SUBSTR ('abcabd', '(.*)\1+'   ) AS C6
  FROM DUAL;
  • REGEXP_SUBSTR('ababab', '(.*)\1+')
    (.*) : 뭔가를 잡아둔다(캡처), 어떤 문자든 상관없고 최대한 많이 잡는다
    (.*)는 "아무 문자열이나 가능한 한 길게" 잡는 것 → 'ababab'에서 (.*)는 처음에 'abab'까지 다 잡아버릴 수도 있움

    \1+ : 방금 잡은 걸 한 번 이상 반복해서 다시 찾는다

    문자열: 'ababab'

    (.*)는 가능한 많이 잡으려 해서 처음엔 'abab'을 잡음
    그러면 \1 :'abab'를 찾으라는 뜻
    그런데 남은 건 'ab'뿐이라 'abab'이 다시 안 나와 → ❌ 실패

    이번엔 (.*)를 'ab'까지만 잡음 → \1 = 'ab'
    남은 건 'abab'인데 'ab'가 또 나와 → ✅ 매치됨!
    📌 결과: 'abab'이 매치돼서 결과로 나옴

문자 리스트 연산자

  • [char…] : 문자 리스트 중 한 문자와 일치
    ex. [abc] : a,b,c
    대괄호 안의 문자 a,b,c 중 하나와 일치
    SELECT REGEXP_SUBSTR ('ac', '[ab]c' ) AS C1 -- ac
    REGEXP_SUBSTR ('bc', '[ab]c' ) -- bc
  • [^char…] : 문자 리스트에 포함되지 않은 한 문자와 일치
    ex. [^abc] : d, e, z…
    대괄호 안의 문자 a,b,c를 제외한 나머지 문자
    REGEXP_SUBSTR ('ac', '[^ab]c') -- NULL
    REGEXP_SUBSTR ('cc', '[^ab]c') -- cc
    a 또는 b가 아닌 문자 + c니까 cc 출력

    연산자 (축약형)설명
    \d숫자 (0~9)
    \D숫자가 아닌 문자
    \w영어 대소문자, 숫자, 언더바(_) 포함
    \W영어/숫자/언더바가 아닌 문자
    \s공백 문자 (스페이스, 탭, 줄바꿈 등)
    \S공백이 아닌 문자
SELECT REGEXP_SUBSTR ('(650) 555-0100', '^\(\d{3}\) \d{3}-\d{4}$') AS C1
     , REGEXP_SUBSTR ('650-555-0100'  , '^\(\d{3}\) \d{3}-\d{4}$') AS C2
     , REGEXP_SUBSTR ('b2b', '\w\d\D') AS C3 -- b2b
     , REGEXP_SUBSTR ('b2_', '\w\d\D') AS C4 -- b2_
     , REGEXP_SUBSTR ('b22', '\w\d\D') AS C5 -- NULL
  FROM DUAL;
  • REGEXP_SUBSTR ('(650) 555-0100', '^(\d{3}) \d{3}-\d{4}') AS C1 ^\(\d{3}\) \d{3}-\d{4}
    ^ : 문자열의 시작
    ( : 여는 괄호 (
    \d{3} : 숫자 3자리
    ) : 닫는 괄호 )
    : 공백

    \d{3} : 숫자 3자리

  • : 하이픈
    \d{4} : 숫자 4자리
    $ : 문자열의 끝

  • REGEXP_SUBSTR ('650-555-0100' , '^(\d{3}) \d{3}-\d{4}$')
    괄호 없어서 안됨

SELECT
  REGEXP_SUBSTR('aiden@company.co.kr', '\w+@\w+(\.\w+)+') AS C1,
  REGEXP_SUBSTR('aiden'             , '\w+@\w+(\.\w+)+') AS C2,
  REGEXP_SUBSTR('to: mae'           , '\w+\W\s\w+')       AS C3,
  REGEXP_SUBSTR('to mae'            , '\w+\W\s\w+')       AS C4
FROM DUAL;
컬럼설명결과
C1이메일 형식 매칭
\w+@\w+(\.\w+)+
→ 영문+숫자+_로 구성된 이메일 주소 전체
aiden@company.co.kr
C2이메일이 아님 → 매칭 실패NULL
C3\w+to
\W:
\s → 공백
\w+mae
to: mae
C4\W에 해당하는 특수문자 없음 (: 없음) → 매칭 실패NULL
SELECT
  REGEXP_SUBSTR('(a b )', '\(\w\s\w\s\)') AS C1,
  REGEXP_SUBSTR('(a b )', '\(\w\S\w\S\)') AS C2,
  REGEXP_SUBSTR('(a,b.)', '\(\w\s\w\s\)') AS C3,
  REGEXP_SUBSTR('(a,b.)', '\(\w\S\w\S\)') AS C4
FROM DUAL;
컬럼설명결과
C1\( → 괄호 시작
\wa
\s → 공백
\wb
\s → 공백
\) → 괄호 닫힘
→ 전체 매칭
(a b )
C2\S는 공백 아님이므로 실패NULL
C3\s는 공백인데 ,.이 있음 → 실패NULL
C4\S는 공백 아닌 문자
a + , + b + . = 매칭 성공
(a,b.)
SELECT
  REGEXP_SUBSTR('aaaa'  , 'a??aa'  ) AS C1,
  REGEXP_SUBSTR('aaaa'  , 'a?aa'   ) AS C2,
  REGEXP_SUBSTR('xaxbxc', '\w*?x\w') AS C3,
  REGEXP_SUBSTR('xaxbxc', '\w*x\w' ) AS C4,
  REGEXP_SUBSTR('abxcxd', '\w+?x\w') AS C5,
  REGEXP_SUBSTR('abxcxd', '\w+x\w' ) AS C6
FROM DUAL;
컬럼설명결과
C1a??aaa를 0~1회 비탐욕적으로 매칭 → 가능한 짧게 잡음 → 'aaa'aaa
C2a?aaa를 0~1회 탐욕적으로 매칭 → 가능한 길게 → 'aaa'aaa
C3\w*?x\w에서 \w*?는 가능한 짧게("") 매칭, 뒤에 x + 글자 1개 → 'xaxbxc'에서 'x' + 'a' 매칭x a
C4\w*x\w는 앞에 단어문자들 가능한 길게(xa) → 'xab'xab
C5\w+?x\w는 최소 1개 단어문자 비탐욕적으로 → 'abx' + cabxc
C6\w+x\w는 단어문자 최대한 많이 (ab) → 'abxc'abxc
SELECT
  REGEXP_SUBSTR('aaaa'  , 'a{2}?'  ) AS C1,
  REGEXP_SUBSTR('aaaa'  , 'a{2}'   ) AS C2,
  REGEXP_SUBSTR('aaaaa ', 'a{2,}?' ) AS C3,
  REGEXP_SUBSTR('aaaaa ', 'a{2,}'  ) AS C4,
  REGEXP_SUBSTR('aaaaa ', 'a{2,4}?') AS C5,
  REGEXP_SUBSTR('aaaaa ', 'a{2,4}' ) AS C6
FROM DUAL;
컬럼설명결과
C1a{2}?a 2개 매칭, 비탐욕 → aaaa
C2a{2}는 고정적으로 2개 매칭 → aaaa
C3a{2,}?는 최소 2개부터 가능한 짧게 매칭 → aaaa
C4a{2,}는 2개 이상 가능한 많이aaaaaaaaaa
C5a{2,4}?는 2~4개 중 짧게 → aaaa
C6a{2,4}는 2~4개 중 길게 → aaaaaaaa

0개의 댓글