POSIX ERE( Extended Regular Expression )

  1. +
  2. ?
  3. |




11. | ( Vertical Bar )

구문 ( Syntax )

<vertical_bar> ::= |
  • 사용 예
    <vertical_bar>
    
    <pattern_expr><vertical_bar>
    
    <vertical_bar><pattern_expr>
    
    <pattern_expr><vertical_bar><pattern_expr>
    

설명 ( Description )

  • '또는', 'or'를 의미한다.
  • 일반적으로, 좌측 <pattern_expr>부터 검사한 뒤, 매칭이 없으면 우측 <pattern_expr>을 검사한다.
    • ex) REGEXP_SUBSTR( 'take', '(m|t)ake' ) => take
    • ex) REGEXP_SUBSTR( 'aaa', 'aa|aaa' ) => aa
    • 예외) PostgreSQL : 예제 확인
  • <patten_expr> 중 하나가 empty string일 경우, 제쳐두고 나머지 <pattern_expr>을 우선적으로 매칭한다.
    • ex) REGEXP_SUBSTR( 'gdb', '|g' ) => 'g'
      • 이 때 그 나머지 <pattern_expr>의 매칭이 없을 경우 zero-length match가 발생한다.
      • ex) REGEXP_SUBSTR( 'abc', '|g' ) => zero-length match
  • 두 <pattern_expr> 모두 empty string일 경우 zero-length match가 발생한다.
    • ex) |
  • <pattern_expr>이 string일 경우, 그 string을 다룬다.
    • ex) trick|treat => trick or treat ( but not trickreat or trictreat )


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( 'abc', 'a|b' ) AS RESULT FROM DUAL;

RESULT
--------------------
a

SQL> SELECT REGEXP_SUBSTR( 'abc', 'b|a' ) AS RESULT FROM DUAL;

RESULT
--------------------
a

SQL> SELECT REGEXP_SUBSTR( 'bbb', 'bb|bbb' ) AS RESULT FROM DUAL;

RESULT
--------------------
bb

SQL> SELECT REGEXP_SUBSTR( 'bbb', 'bbb|bb' ) AS RESULT FROM DUAL;

RESULT
--------------------
bbb

SQL> SELECT REGEXP_SUBSTR( 'ababcdcdcd', '(ab){2}|(cd)+' ) AS RESULT FROM DUAL;

RESULT
------------------------------
abab

SQL> SELECT REGEXP_SUBSTR( 'ababcdcdcd', '(ab){2}|(cd)+', 1, 2 ) AS RESULT FROM DUAL;

RESULT
------------------------------
cdcdcd

SQL> SELECT I1, REGEXP_SUBSTR( I1, '(1[0-2]|0?[1-9])/(3[01]|[12][0-9]|0?[1-9])(st|nd|rd|th)?' ) AS RESULT FROM T1;

I1                             RESULT
------------------------------ ------------------------------
12/25                          12/25
02/14                          02/14
11/26th                        11/26th
4/3rd                          4/3rd
10/01st                        10/01st

SQL> SELECT REGEXP_SUBSTR( 'mississippi', 'mi(s|ss)i(s|ss)i(p|pp)i' ) AS RESULT FROM DUAL;

RESULT
--------------------
mississippi

SQL> SELECT REGEXP_SUBSTR( '801010-1234567',
 '[6-9][0-9]([0][1-9]|[1][0-9])([0][1-9]|[1-2][0-9]|[3][0-1])-[1-4][0-9]{6}' ) AS RESULT FROM DUAL;

RESULT
--------------------
801010-1234567

SQL> SELECT REGEXP_SUBSTR( '800010-1234567',
 '[6-9][0-9]([0][1-9]|[1][0-9])([0][1-9]|[1-2][0-9]|[3][0-1])-[1-4][0-9]{6}' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_SUBSTR( '801010-2234567',
 '[6-9][0-9]([0][1-9]|[1][0-9])([0][1-9]|[1-2][0-9]|[3][0-1])-[1-4][0-9]{6}' ) AS RESULT FROM DUAL;

RESULT
--------------------
801010-2234567

SQL> SELECT REGEXP_SUBSTR( '801010-5234567',
 '[6-9][0-9]([0][1-9]|[1][0-9])([0][1-9]|[1-2][0-9]|[3][0-1])-[1-4][0-9]{6}' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

  • zero-length match : PostgreSQL로 테스트
    postgres=# SELECT REGEXP_MATCHES( 'abc', 'a|', 'g' ) AS RESULT;
     result 
    --------
     {a}
     {""}
     {""}
     {""}
    (4 )
    
    postgres=# SELECT REGEXP_MATCHES( 'abc', '|a', 'g' ) AS RESULT;
     result 
    --------
     {a}
     {""}
     {""}
     {""}
    (4 )
    
    postgres=# SELECT REGEXP_MATCHES( 'abc', 'z|', 'g' ) AS RESULT;
     result 
    --------
     {""}
     {""}
     {""}
     {""}
    (4 )
    
    postgres=# SELECT REGEXP_MATCHES( 'abc', '|z', 'g' ) AS RESULT;
     result 
    --------
     {""}
     {""}
     {""}
     {""}
    (4 )
    
    postgres=# SELECT REGEXP_MATCHES( 'abc', '|', 'g' ) AS RESULT;
     result 
    --------
     {""}
     {""}
     {""}
     {""}
    (4 )
    
    


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX ERE( Extended Regular Expression )

  1. +
  2. ?
  3. |




10. ? ( Question Mark )

구문 ( Syntax )

<question_mark> ::= ?
  • 사용 예
    <pattern_expr><question_mark>
    

설명 ( Description )

  • 0 or 1
  • 수량자(quantifier)로, <question_mark> 앞의 <pattern_expr>이 없거나 하나 있음을 의미한다.
    • ex) a? =>  , a
  • <question_mark>만 있는 경우
    • ex) ?
    • 결과
      • Oracle : zero-length match
      • PostgreSQL, MySQL, MariaDB : error 처리
  • zero-length match가 발생할 수 있다.


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( 'god', 'goo?d' ) AS RESULT FROM DUAL;

RESULT
--------------------
god

SQL> SELECT REGEXP_SUBSTR( 'good', 'goo?d' ) AS RESULT FROM DUAL;

RESULT
--------------------
good

SQL> SELECT REGEXP_SUBSTR( 'goood', 'goo?d' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_SUBSTR( 'ababc', '(ab)?' ) AS RESULT FROM DUAL;

RESULT
--------------------
ab

SQL> SELECT REGEXP_SUBSTR( 'knight', '.?night' ) AS RESULT FROM DUAL;

RESULT
--------------------
knight

SQL> SELECT REGEXP_SUBSTR( 'abc', 'z?' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_COUNT( 'abc', 'z?' ) AS RESULT FROM DUAL;

    RESULT
----------
         4

  • <question_mark>만 있는 경우
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'ab', '?' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'ab', '?' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             3
    
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'ab', '?', 'g' ) AS RESULT;
    ERROR:  invalid regular expression: quantifier operand invalid
    
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'ab', '?' ) AS RESULT;
    ERROR 3688 (HY000): Syntax error in regular expression on line 1, character 1.
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'ab', '?' ) AS RESULT;
    ERROR 1139 (42000): Got error 'nothing to repeat at offset 0' from regexp
    
    


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX ERE( Extended Regular Expression )

  1. +
  2. ?
  3. |



9. + ( Plus )

구문 ( Syntax )

<plus> ::= +
  • 사용 예
    <pattern_expr><plus>
    

설명 ( Description )

  • 1 or MORE
  • 수량자(quantifier)로, <plus> 앞의 <pattern_expr>이 하나 이상 있음을 의미한다.
    • ex) a+ => a, aa, aaa, ...
  • <plus>만 있는 경우
    • ex) +
    • 결과
      • Oracle : zero-length match
      • PostgreSQL, MySQL, MariaDB : error 처리
  • 다른 수량자들과는 달리 zero-length match가 발생하지 않는다.
    • Oracle은 예외적으로 empty string에 대한 +도 zero-length match가 발생한다.
      • ex) +


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( 'aaaaabbb', 'a+' ) AS RESULT FROM DUAL;

RESULT
--------------------
aaaaa

SQL> SELECT REGEXP_SUBSTR( 'abababc', '(ab)+' ) AS RESULT FROM DUAL;

RESULT
--------------------
ababab

SQL> SELECT REGEXP_SUBSTR( 'knight', '.+knight' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_SUBSTR( 'GOLDILOCKS', 'GOLD(.+)' ) AS RESULT FROM DUAL;

RESULT
--------------------
GOLDILOCKS

  • <plus>만 있는 경우
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'ab', '+' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'ab', '+' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             3
    
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'ab', '+', 'g' ) AS RESULT;
    ERROR:  invalid regular expression: quantifier operand invalid
    
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'ab', '+' ) AS RESULT;
    ERROR 3688 (HY000): Syntax error in regular expression on line 1, character 1.
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'ab', '+' ) AS RESULT;
    ERROR 1139 (42000): Got error 'nothing to repeat at offset 0' from regexp
    
    




블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX BRE( Basic Regular Expression )

  1. ^
  2. $
  3. .
  4. *
  5. \
  6. (
  7. {
  8. [




8. [ ] ( Bracket, 대괄호 )

구문 ( Syntax )

<left_bracket> ::= [

<right_bracket> ::= ]
  • 사용 예
    <left_bracket><positive_bracket_expr><right_bracket>
    
    <left_bracket><negative_bracket_expr><right_bracket>
    
    <positive_bracket_expr> ::=
      <bracket_expr>
    
    <negative_bracket> ::=
      <caret><bracket_expr>
    
    <caret> ::= ^
    
    <bracket_expr> ::=
      <specific_character>
    | <range_character>
    | <collation_class>
    | <character_class>
    | <equivalence_class>
    
    <specific_character> ::=
      <pattern_expr>
    
    
    ex) [abc]
    
    <range_character> ::=
      <pattern_expr><hyphen><pattern_expr>
    
    <hyphen> ::= -
    
    
    ex) [0-9]
    
    <collation_class> ::=
      <left_bracket><period><pattern_expr><period><right_bracket>
    
    <period> ::= .
    
    
    ex) [[.Ch.]]
    
    <character_class> ::=
      <left_bracket><colon>alnum<colon><right_bracket>
    | <left_bracket><colon>alpha<colon><right_bracket>
    | <left_bracket><colon>blank<colon><right_bracket>
    | <left_bracket><colon>cntrl<colon><right_bracket>
    | <left_bracket><colon>digit<colon><right_bracket>
    | <left_bracket><colon>graph<colon><right_bracket>
    | <left_bracket><colon>lower<colon><right_bracket>
    | <left_bracket><colon>print<colon><right_bracket>
    | <left_bracket><colon>punct<colon><right_bracket>
    | <left_bracket><colon>space<colon><right_bracket>
    | <left_bracket><colon>upper<colon><right_bracket>
    | <left_bracket><colon>word<colon><right_bracket>
    | <left_bracket><colon>xdigit<colon><right_bracket>
    
    <colon> ::= :
    
    
    ex) [[:alnum:]],  [[:xdigit:]]
    
    <equivalence_class> ::=
      <left_bracket><equal><pattern_expr><equal><right_bracket>
    
    <equal> ::= =
    
    
    ex) [[=e=]]
    

설명 ( Description )

  • 한 문자를 의미하며 사용 방법에 따라 의미가 다양하게 바뀐다.
  • <left_bracket> 이후 다음 문자들을 제외한 나머지 문자들은 모두 일반 문자로 취급한다.
    • ^ ( caret ) : negative
      • ex) [^a]
    • - ( hyphen ) : range
      • ex) [A-Z]
    • [ ( open bracket ) : 각종 클래스
      • 클래스 안에서 : ( colon ).( period )= ( equal )은 각 클래스의 구문으로 쓰인다.
        • ex) [[:cntrl:]]
        • ex) [[.Ch.]]
        • ex) [[=n=]]
    • ] ( close bracket ) : bracket 구문 종료

예를 들어 [*]는 단지 문자 '*'를 의미한다.

  • 종류는 다음과 같다.
    • <specific_character>
    • <range_character>
    • <collation_class>
    • <character_class>
    • <equivalence_class>
<specific_character>
  • <pattern_expr>에 명시된 문자들 중 한 문자를 의미한다.
  • 예시
    [a] : 알파벳 'a'를 의미
    [^a] : 알파벳 'a'가 아닌 다른 한 문자를 의미
    [abc] : 'a' 혹은 'b' 혹은 'c' 중 한 문자를 의미
    [^abc] : 'a', 'b', 'c'를 제외한 한 문자를 의미
    
<range_character>
  • <hyphen>을 사용하며 명시된 <character_1>과 <character_2> 범위 내의 한 문자를 의미한다.
  • 범위의 순서 기준은 ASCII 코드이다.
  • <character_1>의 ASCII 코드 숫자가 <character_2>의 ASCII 코드 숫자보다 크면 error 처리한다.
  • 한글도 가능하며, 한글 순서의 기준은 추후에 다룬다.
  • 예시
    [a-z] : 알파벳 소문자 한 문자를 의미 ( ASCII code 97 ~ 122 )
    [0-9] : 10진 수 0~9중 한 문자를 의미 ( ASCII code 48 ~ 57 )
    [A-Za-z] : 알파벳 대문자 및 소문자 한 문자를 의미
    [a-a] : 알파벳 a를 의미
    [b-a] : error
    
<collation_class>
  • multibyte 문자가 한 문자를 의미할 때, 이 collation class를 사용하여 나타낸다.
  • NLS_LANGUAGE와 NLS_SORT를 사용해야하며, 해당 국가의 문자가 알파벳으로 표현하였을 때 두 개 이상일 때
    그 문자들을 한 문자로 처리한다.
  • 국가별로 해당 예약어가 정해져 있다.
  • 예시
    ALTER SESSION SET NLS_LANGUAGE=SPANISH;
    ALTER SESSION SET NLS_SORT=XSPANISH;
    
    source string : El caballo, Chico come la tortilla
    pattern : [[.ch.]]
    
    matched result : Ch
    
<character_class>
  • 각 문자 클래스가 의미하는 문자들 중 한 문자를 의미한다.
  • 문자 클래스의 종류는 다음과 같다.
클래스 이름설명ASCII CODE range비고
[:alnum:]알파벳과 숫자(48 ~ 57), (65 ~ 90), (97 ~ 122) 
총 62개
[:alpha:]알파벳(65 ~ 90), (97 ~ 122)
총 52개
[:blank:]공백( 스페이스 )(32)
총 1개
[:cntrl:]제어 문자( ^[, ^E 등 )(0 ~ 31), (127)
총 33개
[:digit:]10진수(48 ~ 57)
총 10개
[:graph:]visible한 모든 문자( 공백 제외 )(33 ~ 126)
총 94개
[:lower:]알파벳 소문자(97 ~ 122)
총 26개
[:print:]visible한 모든 문자( 공백 포함 )(32 ~ 126)
총 95개
[:punct:]구두점 문자(33~47), (58~64), (91~96), (123~126)
총 32개
[:space:]모든 공백 문자( [:blank:], newline, carriage return, ... )(9 ~ 13), (32)
총 6개
[:upper:]알파벳 대문자(65 ~ 90)
총 26개
[:word:]알파벳과 숫자,언더바(48 ~ 57), (65 ~ 90), (95), (97 ~ 122) 
총 63개
POSIX 표준이 아님
[:xdigit:]16진수, [A-Fa-f0-9]와 동일함(48 ~ 57), (65 ~ 70), (97 ~ 102)
총 22개
<equivalence_class>
  • equivalence class 는 해당 <pattern_expr>과 동치인 의미를 가진 다른 multibyte 문자들 중 한 문자를 의미한다.
  • 이는 해당 database의 지원 locale 룰에 따라 범주가 달라진다.
  • 예시
    [=n=] : n, N, ñ, El Niño, ...
    

예제 ( Examples )

  • specific character
    SQL> SELECT REGEXP_SUBSTR( 'abc', '[a]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '[ab]', 1, 1 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '[ab]', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    b
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '[^ab]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    c
    
    SQL> SELECT REGEXP_SUBSTR( 'abbccc', '[ab^]+' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    abb
    
    SQL> SELECT REGEXP_SUBSTR( 'ab bccc', '[ab^]+', 1, 1 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SQL> SELECT REGEXP_SUBSTR( 'ab bccc', '[ab^]+', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    b
    
    SQL> SELECT REGEXP_SUBSTR( '^', '[a^]' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    ^
    
    SQL> SELECT REGEXP_SUBSTR( 'b^', '[a^b]' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    b
    
    SQL> SELECT REGEXP_SUBSTR( 'b^', '[^b]' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    ^
    
    SQL> SELECT REGEXP_SUBSTR( 'b^', '[ ^b]' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    b
    
    SQL> SELECT REGEXP_SUBSTR( 'b^', '[ ^b]', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    ^
    
    SQL> SELECT REGEXP_SUBSTR( 'abbccc', '[^^ab]+' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ccc
    
      앞의 ^ 아니면, 단지 스트링 ^취급한다.
    
    
  • range character
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[a-z]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[A-Z]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    C
    
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[^a-zA-Z]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    1
    
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[a--z]' ) AS RESULT FROM DUAL;
    SELECT REGEXP_SUBSTR( 'abCD12<>?', '[a--z]' ) AS RESULT FROM DUAL
                                       *
    ERROR at line 1:
    ORA-12728: invalid range in regular expression
    
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[0-9]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    1
    
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[^0-9]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    
    SQL> SELECT REGEXP_SUBSTR( 'abCD12<>?', '[:-@]' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    <
    
    
  • collation class
    < Oracle >
    SQL> ALTER SESSION SET NLS_LANGUAGE=SPANISH;
    
    Sesión modificada.
    
    SELECT REGEXP_SUBSTR(
       'El caballo, Chico come la tortilla.',
       '[[:alpha:]]*[ch][[:alpha:]]*',1,1,'i') AS RESULT
        FROM dual;
    
    RESULT
    ---------------------
    caballo
    
    SQL> ALTER SESSION SET NLS_SORT=XSPANISH;
    
    Sesión modificada.
    
    SELECT REGEXP_SUBSTR(
       'El caballo, Chico come la tortilla.',
       '[[:alpha:]]*[[.ch.]][[:alpha:]]*',1,1,'i') AS RESULT
        FROM dual;
    
    RESULT
    ---------------
    Chico
    
    < PostgreSQL >
    Note: PostgreSQL currently does not support multi-character collating elements.
    
    < MySQL >
    The Spencer library supports collating element bracket expressions ([.characters.] notation). 
    ICU( International Components for Unicode ) does not.
    
    
  • character class
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:ALNUM:]]+' ) AS RESULT FROM DUAL;
    SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:ALNUM:]]+' ) AS RESULT FROM DUAL
                                      *
    ERROR at line 1:
    ORA-12729: invalid character class in regular expression
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'aBcD1234', '[[:ALNUM:]]+' ) AS RESULT;
    ERROR:  invalid regular expression: invalid character class
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:ALNUM:]]+' ) AS RESULT;
    +----------+
    | RESULT   |
    +----------+
    | aBcD1234 |
    +----------+
    1 row in set (0.00 sec)
    
    
     case sensitive Oracle PostgreSQL, 문자 클래스를 대문자로 표기하면 에러처리한다.
     반면, case insensitive MySQL 문자 클래스도 대문자로 표기 가능하다.
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:alnum:]]+' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    aBcD1234
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:alpha:]]+' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    aBcD
    
    SQL> SELECT REGEXP_SUBSTR( 'a b', 'a[[:blank:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a b
    
    SQL> SELECT REGEXP_SUBSTR( 'a'||CHR(32)||'b', 'a[[:blank:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a b
    
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(0)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(1)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(2)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(3)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(4)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(5)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(6)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(7)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(8)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    b
    
    SQL> SELECT REGEXP_SUBSTR( 'a'||CHR(9)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a       b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(10)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    b
    
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(11)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
     b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(12)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
     b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(13)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(14)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(15)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(16)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(17)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(18)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SQL> SELECT REGEXP_SUBSTR( 'a'||CHR(19)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(20)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(21)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(22)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(23)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(24)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(25)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(26)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(27)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(28)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SQL> SELECT REGEXP_SUBSTR( 'a'||CHR(29)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(30)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(31)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(32)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'a'||CHR(127)||'b', 'a[[:cntrl:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    ab
    
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:digit:]]+' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    1234
    
    SQL> SELECT REGEXP_SUBSTR( 'Right Now!', '[[:graph:]]+', 1, 1 ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    Right
    
    SQL> SELECT REGEXP_SUBSTR( 'Right Now!', '[[:graph:]]+', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    Now!
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:lower:]]+', 1, 1 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:lower:]]+', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    c
    
    SQL> SELECT REGEXP_SUBSTR( 'Right Now!', '[[:print:]]+' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    Right Now!
    
    SQL> SELECT I1, REGEXP_SUBSTR( I1, '[[:punct:]]+' ) AS RESULT FROM T1;
    
    I1                                            RESULT
    --------------------------------------------- --------------------
    !"#$%&'()*+,-./                               !"#$%&'()*+,-./
    :;<=>?@                                       :;<=>?@
    [\]^_`                                        [\]^_`
    {|}~                                          {|}~
    
    
    SQL> SELECT REGEXP_SUBSTR( 'a'||CHR(9)||'b', 'a[[:space:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a       b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(10)||'b', 'a[[:space:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
    b
    
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(11)||'b', 'a[[:space:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
     b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(12)||'b', 'a[[:space:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a
     b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(13)||'b', 'a[[:space:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    b
    
    SELECT REGEXP_SUBSTR( 'a'||CHR(32)||'b', 'a[[:space:]]b' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    a b
    
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:upper:]]+', 1, 1 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    B
    
    SQL> SELECT REGEXP_SUBSTR( 'aBcD1234', '[[:upper:]]+', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    D
    
    SQL> SELECT REGEXP_SUBSTR( 'AEd019', '[[:xdigit:]]+' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    AEd019
    
    SQL> SELECT REGEXP_SUBSTR( 'AEGd019', '[[:xdigit:]]+', 1, 1 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    AE
    
    SQL> SELECT REGEXP_SUBSTR( 'AEGd019', '[[:xdigit:]]+', 1, 2 ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    d019
    
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '[[:word:]]+' ) AS RESULT FROM DUAL;
    SELECT REGEXP_SUBSTR( 'abc', '[[:word:]]+' ) AS RESULT FROM DUAL
                                 *
    ERROR at line 1:
    ORA-12729: invalid character class in regular expression
    
    postgres=# SELECT REGEXP_MATCHES( 'abc', '[[:word:]]+' ) AS RESULT;
    ERROR:  invalid regular expression: invalid character class
    
    mysql> SELECT REGEXP_SUBSTR( 'abCD987_', '[[:word:]]+' ) AS RESULT;
    +----------+
    | RESULT   |
    +----------+
    | abCD987_ |
    +----------+
    1 row in set (0.02 sec)
    
     [:word:] character class POSIX 표준이 아닌 Perl 호환 정규 표현식이며 Oracle, PostgreSQL에서 지원하지 않는다.
    
    • 고려사항
      • Bracket 짝이 맞지 않을 때
        < Oracle >
        SQL> SELECT REGEXP_SUBSTR( '[digit]', '[:digit:]]' ) AS RESULT FROM DUAL;
        
        RESULT
        --------------------
        t]
        
        SQL> SELECT REGEXP_SUBSTR( '[digit]', '[[:digit:]' ) AS RESULT FROM DUAL;
        SELECT REGEXP_SUBSTR( '[digit]', '[[:digit:]' ) AS RESULT FROM DUAL
                                        *
        ERROR at line 1:
        ORA-12726: unmatched bracket in regular expression
        
        
        < PostgreSQL >
        postgres=# SELECT REGEXP_MATCHES( '[digit]', '[:digit:]]' ) AS RESULT;
         result 
        --------
         {t]}
        (1 )
        
        postgres=# SELECT REGEXP_MATCHES( '[digit]', '[[:digit:]' ) AS RESULT;
        ERROR:  invalid regular expression: brackets [] not balanced
        
        
        < MySQL >
        mysql> SELECT REGEXP_SUBSTR( '[digit]', '[:digit:]]' ) AS RESULT;
        +--------+
        | RESULT |
        +--------+
        | NULL   |
        +--------+
        1 row in set (0.00 sec)
        
        mysql> SELECT REGEXP_SUBSTR( '[digit1]', '[:digit:]]' ) AS RESULT;
        +--------+
        | RESULT |
        +--------+
        | 1]     |
        +--------+
        1 row in set (0.00 sec)
        
        mysql> SELECT REGEXP_SUBSTR( '[digit]', '[[:digit:]' ) AS RESULT;
        ERROR 3696 (HY000): The regular expression contains an unclosed bracket expression.
        
        
        < MariaDB >
        MariaDB [test]> SELECT REGEXP_SUBSTR( '[digit]', '[:digit:]]' ) AS RESULT;
        ERROR 1139 (42000): Got error 'POSIX named classes are supported only within a class at offset ' from regexp
        MariaDB [test]> SELECT REGEXP_SUBSTR( '[digit1]', '[:digit:]]' ) AS RESULT;
        ERROR 1139 (42000): Got error 'POSIX named classes are supported only within a class at offset ' from regexp
        
        
         MySQL, MariaDB 처리가  다르지만,  벤더 모두 닫히지 않은 bracket 대한 에러 처리는 당연히 동일하다.
        
      • caret의 위치
        • [^[:class_name:]]   [[^:class_name:]]   [[:^class_name:]]   비교
        • Oracle
          # Not digit #
          
          SQL> SELECT REGEXP_SUBSTR( '1d]', '[^[:digit:]]' ) AS RESULT FROM DUAL;
          
          RESULT
          --------------------
          d
          
          
          # specific character & string ']' #
          
          SQL> SELECT REGEXP_SUBSTR( '1d]', '[[^:digit:]]' ) AS RESULT FROM DUAL;
          
          RESULT
          --------------------
          d]
          
          SQL> SELECT REGEXP_SUBSTR( '1d[]', '[[^:digit:]]' ) AS RESULT FROM DUAL;
          
          RESULT
          ------------------------------
          []
          
          
          SQL> SELECT REGEXP_SUBSTR( '1d]', '[[:^digit:]]' ) AS RESULT FROM DUAL;
          SELECT REGEXP_SUBSTR( '1d]', '[[:^digit:]]' ) AS RESULT FROM DUAL
                                       *
          ERROR at line 1:
          ORA-12729: invalid character class in regular expression
          
          
          
        • PostgreSQL
          # Not digit #
          
          postgres=# SELECT REGEXP_MATCHES( '1d]', '[^[:digit:]]', 'g' ) AS RESULT;
           result 
          --------
           {d}
           {]}
          (2 )
          
          
          # specific character & string ']' #
          
          postgres=# SELECT REGEXP_MATCHES( '1d]', '[[^:digit:]]', 'g' ) AS RESULT;
           result 
          --------
           {d]}
          (1 )
          
          postgres=# SELECT REGEXP_MATCHES( '1d[]', '[[^:digit:]]', 'g' ) AS RESULT;
           result 
          --------
           {[]}
          (1 )
          
          
          postgres=# SELECT REGEXP_MATCHES( '1d]', '[[:^digit:]]', 'g' ) AS RESULT;
          ERROR:  invalid regular expression: invalid character class
          
          
        • MySQL
          # Not digit #
          
          mysql> SELECT REGEXP_SUBSTR( '1d]', '[^[:digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | d      |
          +--------+
          1 row in set (0.00 sec)
          
          
          # negative specific character same as [^:digit:] #
          
          mysql> SELECT REGEXP_SUBSTR( '1d]', '[[^:digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | 1      |
          +--------+
          1 row in set (0.01 sec)
          
          mysql> SELECT REGEXP_SUBSTR( '1d]', '[[^:digit:]]', 1, 2 ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | ]      |
          +--------+
          1 row in set (0.01 sec)
          
          mysql> SELECT REGEXP_SUBSTR( ':digit:1d]', '[[^:digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | 1      |
          +--------+
          1 row in set (0.01 sec)
          
          
          # Not digit #
          
          mysql> SELECT REGEXP_SUBSTR( '1d]', '[[:^digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | d      |
          +--------+
          1 row in set (0.03 sec)
          
          
        • MariaDB
          # Not digit #
          
          MariaDB [test]> SELECT REGEXP_SUBSTR( '1d]', '[^[:digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | d      |
          +--------+
          1 row in set (0.001 sec)
          
          
          # specific character & string ']' #
          
          MariaDB [test]> SELECT REGEXP_SUBSTR( '1d]', '[[^:digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | d]     |
          +--------+
          1 row in set (0.000 sec)
          
          MariaDB [test]> SELECT REGEXP_SUBSTR( '1d[]', '[[^:digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | []     |
          +--------+
          1 row in set (0.001 sec)
          
          
          # Not digit #
          
          MariaDB [test]> SELECT REGEXP_SUBSTR( '1d]', '[[:^digit:]]' ) AS RESULT;
          +--------+
          | RESULT |
          +--------+
          | d      |
          +--------+
          1 row in set (0.000 sec)
           
caret의 위치에 따른 문자 클래스의 벤더별 처리
 DBMS  [^[:class_name:]]  [[^:class_name:]]  [[:^class_name:]] 
 Oracle  negative class  normal bracket  error 
 PostgreSQL  negative class  normal bracket  error 
 MySQL  negative class  same as [^:class_name:]  negative class 
 MariaDB  negative class  normal bracket  negative class 
  • equivalence class
    SQL> SELECT REGEXP_SUBSTR('eéëèÉËÈE', '[[=e=]]+') AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------------------
    eéëèÉËÈE
    
    SQL> SELECT REGEXP_SUBSTR('eéëèÉËÈE', '[[=E=]]+') AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------------------
    eéëèÉËÈE
    
    SQL> SELECT REGEXP_SUBSTR('eéëèÉËÈE', '[[=É=]]+') AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------------------
    eéëèÉËÈE
    
     PostgreSQL, MySQL, MariaDB에서는 지원하지 않음.


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX BRE( Basic Regular Expression )

  1. ^
  2. $
  3. .
  4. *
  5. \
  6. (
  7. {
  8. [




7. { } ( Brace, 중괄호 )

구문 ( Syntax )

<left_brace> ::= {

<right_brace> ::= }
  • 사용 예
    <pattern_expr><left_brace><brace_expr><right_brace>
    
    <brace_expr> ::=
      <integer_1>
    | <integer_1><comma>
    | <integer_1><comma><integer_2>
    
    <comma> ::= ,
    
    

설명 ( Description )

  • 수량자(quantifier)로, <left_brace> 앞에 있는 <pattern_expr>의 '개수, 반복 횟수'를 의미한다.
  • <brace_expr>에 하나의 <integer_1> 만 명시한 경우
    • 정확히 <integer>개를 의미한다.
      • ex) a{2} => aa
      • ex) (ab){3} => ababab
  • <brace_expr>에 <integer_1>와 <comma>를 명시한 경우
    • <integer>개 이상을 의미한다.
      • ex) a{3,} => aaa, aaaa, aaaaa, ...
  • <brace_expr>에 <integer_1>, <comma>, <integer_2>를 명시한 경우
    • <integer_1>개 이상 <integer_2>개 이하를 의미한다.
      • ex) go{1, 3} => go, goo, gooo
    • <integer_1> ≤ <integer_2> 를 만족해야 한다. ( <integer_1> > <integer_2> 인 경우 error 처리 )
      • ex) (ab){5,2} => error 처리
  • 지정된 사용법이 아닌 경우
    • <integer_1>에 음수 및 소수가 있는 경우
      • ex) a{-1}
      • ex) z{1.5}
    • <comma>가 아닌 다른 문자가 있는 경우( 숫자 아닌 문자 )
      • ex) g{1~10}
    • <comma> 뒤에 <integer_2>가 아닌 다른 문자가 있는 경우
      • ex) (ab){2,s}
    • 맨 뒤에 <right_brace>가 없는 경우
      • ex) c{3,5
    • 결과
      • Oracle, MariaDB는 전체를 str (일반 문자)로 처리한다.
      • PostreSQL, MySQL은 error 처리한다.
  • <integer_1> 이 0인 경우, zero-length match가 발생할 수 있다.

    • ex) c{0}
    • ex) z{0,}
    • ex) (ab){0, 5}
  • <brace_expr>에 아무것도 명시하지 않은 경우
    • ex) a{}
    • 결과
      • Oracle, PostgreSQL, MariaDB : string 처리
      • MySQL : error 처리
  • <pattern_expr>이 <left_brace> 앞에 명시되어있지 않은 경우
    • ex) {3}
    • 결과
      • Oracle : zero-length match
      • PostgreSQL, MySQL, MariaDB : error 처리


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( 'aaaab', 'a{2}' ) AS RESULT FROM DUAL;

RESULT
--------------------
aa

SQL> SELECT REGEXP_SUBSTR( 'aaaab', 'a{1,}' ) AS RESULT FROM DUAL;

RESULT
--------------------
aaaa

SQL> SELECT REGEXP_SUBSTR( 'aaaab', 'a{1,3}' ) AS RESULT FROM DUAL;

RESULT
--------------------
aaa

  • 지정된 사용법이 아닌 경우
    SQL> SELECT REGEXP_SUBSTR( 'aaa', 'a{-1}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'a{-1}', 'a{-1}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a{-1}
    
    SQL> SELECT REGEXP_SUBSTR( 'aaa', 'a{1~3}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'a{1~3}', 'a{1~3}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a{1~3}
    
    SQL> SELECT REGEXP_SUBSTR( 'aaa', 'a{1.5}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'a{1.5}', 'a{1.5}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a{1.5}
    
    SQL> SELECT REGEXP_SUBSTR( 'zzz', 'z{1,a}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'z{1,a}', 'z{1,a}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    z{1,a}
    
    SQL> SELECT REGEXP_SUBSTR( 'zzz', 'z{1, 2}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'z{1, 2}', 'z{1, 2}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    z{1, 2}
    
    SQL> SELECT REGEXP_SUBSTR( 'aaa', 'a{1' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'a{1', 'a{1' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a{1
    
    SQL> SELECT REGEXP_SUBSTR( 'zzz', 'z{1,' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'z{1,', 'z{1,' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    z{1,
    
    SQL> SELECT REGEXP_SUBSTR( 'zzz', 'z{1,3' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'z{1,3', 'z{1,3' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    z{1,3
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'a{1~3}', 'a{1~3}' ) AS RESULT FROM DUAL;
    +--------+
    | RESULT |
    +--------+
    | a{1~3} |
    +--------+
    1 row in set (0.001 sec)
    
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'a{1,3', 'a{1~3}' ) AS RESULT;
    ERROR:  invalid regular expression: invalid repetition count(s)
    
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'aaa', 'a{1~3}' ) AS RESULT FROM DUAL;
    ERROR 3692 (HY000): Incorrect description of a {min,max} interval.
    
    
     Oracle, MariaDB 지정된 사용법이 아니라면 모두 string 처리하는 반면
       PostgreSQL, MySQL error 처리한다.
    
  • <integer>, <integer_1> 이 0인 경우
    SQL> SELECT REGEXP_SUBSTR( 'abc', 'z{0}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'abc', 'z{0}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             4
    
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', 'z{0,}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'abc', 'z{0,}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             4
    
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', 'z{0,10}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'abc', 'z{0,10}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             4
    
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '(abc){0}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'abc', '(abc){0}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             4
    
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '(abc){0,}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    abc
    
    SQL> SELECT REGEXP_COUNT( 'abc', '(abc){0,}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             2
    
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '(def){0,}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'abc', '(def){0,}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             4
    
  • <brace_expr>에 아무것도 명시하지 않은 경우
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'aaa', 'a{}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_SUBSTR( 'a{}', 'a{}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    a{}
    
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'aaa', 'a{}', 'g' ) AS RESULT;
     result 
    --------
    (0 )
    
    postgres=# SELECT REGEXP_MATCHES( 'a{}', 'a{}', 'g' ) AS RESULT;
     result  
    ---------
     {"a{}"}
    (1 )
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'aaa', 'a{}' ) AS RESULT;
    +--------+
    | RESULT |
    +--------+
    |        |
    +--------+
    1 row in set (0.001 sec)
    
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'a{}', 'a{}' ) AS RESULT;
    +--------+
    | RESULT |
    +--------+
    | a{}    |
    +--------+
    1 row in set (0.001 sec)
    
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'aaa', 'a{}' ) AS RESULT;
    ERROR 3692 (HY000): Incorrect description of a {min,max} interval.
    
    
     Oracle, PostgreSQL, MariaDB 모두 string 처리하는 반면
       MySQL error 처리한다.
    
  • <pattern_expr>이 <left_brace> 앞에 명시되어있지 않은 경우
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'aaa', '{5}' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'aaa', '{5}' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             4
    
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'aaa', '{5}', 'g' ) AS RESULT;
    ERROR:  invalid regular expression: quantifier operand invalid
    
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'aaa', '{5}' ) AS RESULT;
    ERROR 3688 (HY000): Syntax error in regular expression on line 1, character 1.
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'aaa', '{5}' ) AS RESULT;
    ERROR 1139 (42000): Got error 'nothing to repeat at offset 2' from regexp
    
    


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX BRE( Basic Regular Expression )

  1. ^
  2. $
  3. .
  4. *
  5. \
  6. (
  7. {
  8. [



5. \ ( Back Slash )

구문 ( Syntax )

<back_slash> ::= \
  • 사용 예
    <back_slash><meta_char>
    
    <meta_char> ::=
      ^
    | $
    | .
    | *
    | +
    | ?
    | |
    | \
    | (
    | )
    | {
    | [
    
    

설명 ( Description )

  • <back_slash> 뒤의 <meta_char>가 문자 그대로임을 의미한다. ( 이스케이프 처리 )
    • ex) \^
  • <back_slash>만 있는 경우
    • ex) \
    • 결과
      • Oracle : zero-length match
      • PostgreSQL, MySQL, MariaDB : error 처리
  • <back_slash> 뒤에 <meta_char>가 아닌 일반 문자가 있는 경우, 아무런 효과 없이 그 문자만을 매칭한다.
    • ex) \j
  • <back_slash> 뒤에 숫자가 올 수 없다.
    • ex) \1


MariaDB와 MySQL에서는 두 개( \\ )를 사용한다.




문자마다 매번 \를 사용하면 알아보기가 힘들어지기 때문에,

Perl, JAVA는 '\Q'와 '\E'를 사용해 이스케이프처리를 한 번에 할 수 있다.


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( '$999', '\$999' ) AS RESULT FROM DUAL;

RESULT
--------------------
$999

SQL> SELECT REGEXP_SUBSTR( 'Hi ^^', 'Hi \^\^' ) AS RESULT FROM DUAL;

RESULT
--------------------
Hi ^^

SQL> SELECT REGEXP_SUBSTR( 'Mr.Kim', 'Mr\.Kim' ) AS RESULT FROM DUAL;

RESULT
--------------------
Mr.Kim

SQL> SELECT REGEXP_SUBSTR( '\n means ''new line''', '\\.*' ) AS RESULT FROM DUAL;

RESULT
--------------------
\n means 'new line'

  • <back_slash>만 있는 경우
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'SUNJE', '\' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'SUNJE', '\' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             6
    
    
    < PostgreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'SUNJE', '\', 'g' ) AS RESULT;
    ERROR:  invalid regular expression: invalid escape \ sequence
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'SUNJE', '\\' ) AS RESULT;
    ERROR 3689 (HY000): Unrecognized escape sequence in regular expression.
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'SUNJE', '\\' ) AS RESULT;
    ERROR 1139 (42000): Got error '\ at end of pattern at offset 1' from regexp
    
    
  • <back_slash> 뒤에 일반 문자가 있는 경우
    SQL> SELECT REGEXP_SUBSTR( 'yo', '\yo' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    yo
    
    SQL> SELECT REGEXP_SUBSTR( 'abc', '\a\b\c' ) AS RESULT FROM DUAL;
    
    RESULT
    --------------------
    abc
    
    
  • <back_slash> 뒤에 숫자가 있는 경우
    SQL> SELECT REGEXP_SUBSTR( '123', '\123' ) AS RESULT FROM DUAL;
    SELECT REGEXP_SUBSTR( '123', '\123' ) AS RESULT FROM DUAL
                                 *
    ERROR at line 1:
    ORA-12727: invalid back reference in regular expression
    
    이스케이프 뒤의 숫자는 허용하지 않는다.
    



블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX BRE( Basic Regular Expression )

  1. ^
  2. $
  3. .
  4. *
  5. \
  6. (
  7. {
  8. [




4. * ( Asterisk )

구문 ( Syntax )

<asterisk> ::= *
  • 사용 예
    <pattern_expr><asterisk>
    

설명 ( Description )

  • 0 or MORE
  • 수량자(quantifier)로, <asterisk> 앞의 <pattern_expr>이 없거나 하나 이상 있음을 의미한다.
    • ex) a* =>  , a, aa, aaa, ...
  • <asterisk>만 있는 경우
    • ex) *
    • 결과
      • Oracle : zero-length match
      • PostgreSQL, MySQL, MariaDB : error 처리
  • zero-length match가 발생할 수 있다. ( 이에 대해선 다음에 다시 설명 )


수량자(quantifier)란?

수량자는 주어진 <pattern_expr>의 수량(quantity)을 지정해주는 메타문자이다.
일반적으로 수량자는가능한 많은 문자와 매칭 시키려는 성질을 가지고 있다.


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( 'aaaaabbb', 'a*' ) AS RESULT FROM DUAL;

RESULT
--------------------
aaaaa

SQL> SELECT REGEXP_SUBSTR( 'abababc', '(ab)*' ) AS RESULT FROM DUAL;

RESULT
--------------------
ababab

SQL> SELECT REGEXP_SUBSTR( 'knight', '.*knight' ) AS RESULT FROM DUAL;

RESULT
--------------------
knight

SQL> SELECT REGEXP_SUBSTR( 'GOLDILOCKS', 'GOLD(.*)' ) AS RESULT FROM DUAL;

RESULT
--------------------
GOLDILOCKS

SQL> SELECT REGEXP_SUBSTR( 'abc', 'z*' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_COUNT( 'abc', 'z*' ) AS RESULT FROM DUAL;

    RESULT
----------
         4

  • <asterisk>만 있는 경우
    < Oracle >
    SQL> SELECT REGEXP_SUBSTR( 'ab', '*' ) AS RESULT FROM DUAL;
    
    RESULT
    ------------------------------
    NULL
    
    SQL> SELECT REGEXP_COUNT( 'ab', '*' ) AS RESULT FROM DUAL;
    
        RESULT
    ----------
             3
    
    
    < PostreSQL >
    postgres=# SELECT REGEXP_MATCHES( 'ab', '*', 'g' ) AS RESULT;
    ERROR:  invalid regular expression: quantifier operand invalid
    
    
    < MySQL >
    mysql> SELECT REGEXP_SUBSTR( 'ab', '*' ) AS RESULT;
    ERROR 3688 (HY000): Syntax error in regular expression on line 1, character 1.
    
    
    < MariaDB >
    MariaDB [test]> SELECT REGEXP_SUBSTR( 'ab', '*' ) AS RESULT;
    ERROR 1139 (42000): Got error 'nothing to repeat at offset 0' from regexp
    
    


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,

POSIX BRE( Basic Regular Expression )

  1. ^
  2. $
  3. .
  4. *
  5. \
  6. (
  7. {
  8. [




3. . ( Period )

구문 ( Syntax )

<period> ::= .

설명 ( Description )

  • 임의의 한 문자를 의미한다.
  • newline 문자( ASCII(10)인 Line Feed(\n) ), NULL은 매칭하지 않는다.


예제 ( Examples )

SQL> SELECT REGEXP_SUBSTR( 'A', '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
A

SQL> SELECT REGEXP_SUBSTR( 'a', '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
a

SQL> SELECT REGEXP_SUBSTR( '7', '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
7

SQL> SELECT REGEXP_SUBSTR( '%', '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
%

SQL> SELECT REGEXP_SUBSTR( '_', '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
_

SQL> SELECT REGEXP_SUBSTR( CHR(10), '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_COUNT( CHR(10), '.' ) AS RESULT FROM DUAL;

    RESULT
----------
         0

SQL> SELECT REGEXP_SUBSTR( NULL, '.' ) AS RESULT FROM DUAL;

RESULT
--------------------
NULL

SQL> SELECT REGEXP_COUNT( NULL, '.' ) AS RESULT FROM DUAL;

    RESULT
----------
NULL


블로그 이미지

차트

소소한 일상 C코드 DB 항상 행복하게^-^★

,