복붙노트

[SQL] REGEXP_SUBSTR 오라클의 구분 기호로 공간과 문자로 분할 문자열

SQL

REGEXP_SUBSTR 오라클의 구분 기호로 공간과 문자로 분할 문자열

나는 regexp_subtr로 문자열을 분할하기 위해 노력하고있어,하지만 난 그것을 작업을 할 수 없습니다.

그래서, 첫째,이 쿼리가

select regexp_substr('Helloworld - test!' ,'[[:space:]]-[[:space:]]') from dual

이는 아주 멋지게 내 구분 기호를 추출 - 빈 공백을

내가이 옵션을 사용하여 문자열을 분할 할 때 그런데, 그냥 작동하지 않습니다.

select regexp_substr('Helloworld - test!' ,'[^[[:space:]]-[[:space:]]]+')from dual

쿼리는 아무 것도 반환하지 않습니다.

도움이 많이 이해할 수있을 것이다! 감사

해결법

  1. ==============================

    1.SQL 바이올린

    SQL 바이올린

    오라클 11g R2 스키마 설정 :

    CREATE TABLE TEST( str ) AS
              SELECT 'Hello world - test-test! - test' FROM DUAL
    UNION ALL SELECT 'Hello world2 - test2 - test-test2' FROM DUAL;
    

    쿼리 1 :

    SELECT Str,
           COLUMN_VALUE AS Occurrence,
           REGEXP_SUBSTR( str ,'(.*?)([[:space:]]-[[:space:]]|$)', 1, COLUMN_VALUE, NULL, 1 ) AS split_value
    FROM   TEST,
           TABLE(
             CAST(
               MULTISET(
                 SELECT LEVEL
                 FROM   DUAL
                 CONNECT BY LEVEL < REGEXP_COUNT( str ,'(.*?)([[:space:]]-[[:space:]]|$)' )
               )
               AS SYS.ODCINUMBERLIST
             )
           )
    

    결과 :

    |                               STR | OCCURRENCE |  SPLIT_VALUE |
    |-----------------------------------|------------|--------------|
    |   Hello world - test-test! - test |          1 |  Hello world |
    |   Hello world - test-test! - test |          2 |   test-test! |
    |   Hello world - test-test! - test |          3 |         test |
    | Hello world2 - test2 - test-test2 |          1 | Hello world2 |
    | Hello world2 - test2 - test-test2 |          2 |        test2 |
    | Hello world2 - test2 - test-test2 |          3 |   test-test2 |
    
  2. ==============================

    2.내가 제대로 이해하면, 이것은 당신을 도움이 될 것입니다. 현재 당신은 (끝에 공간)하여 HelloWorld로 출력을 얻고있다. 내가 가정 그래서 u는 끝 부분에 공간을 갖고 싶어하지 않습니다. 당신은 단순히 구분 기호에 공간을 사용할 수 있도록도 좋아합니다.

    내가 제대로 이해하면, 이것은 당신을 도움이 될 것입니다. 현재 당신은 (끝에 공간)하여 HelloWorld로 출력을 얻고있다. 내가 가정 그래서 u는 끝 부분에 공간을 갖고 싶어하지 않습니다. 당신은 단순히 구분 기호에 공간을 사용할 수 있도록도 좋아합니다.

    select regexp_substr('Helloworld - test!' ,'[^ - ]+',1,1)from dual;
    
    OUTPUT
    Helloworld(No space at the end)
    

    내가 당신의 코멘트에서 언급 한 바와 같이 유 helloworld를 테스트와 두 개의 열 출력을 원한다면! 다음을 수행 할 수 있습니다.

    select regexp_substr('Helloworld - test!' ,'[^ - ]+',1,1),
           regexp_substr('Helloworld - test!' ,'[^ - ]+',1,3) from dual;
    
    OUTPUT
    col1         col2
    Helloworld   test!
    
  3. ==============================

    3.그것이 작동하지 않습니다 부정하는 곡절 (^)로 문자 클래스에 넣어 - '[] : 공간 [] [: 공간] []'경기 문자열을 부정하려고합니다. 대괄호 사이에있는 모든이 방식으로 인해 문자 클래스 둥지에, 그러나, 옵션 문자 목록에 밖으로 확장이라는 이름의 문자 클래스를 제외하고 선택적 단일 문자 목록으로 처리됩니다, 그것은 매우 가능성이 바깥 쪽 괄호가 있음을의 다음과 같이 해석되는 :

    그것이 작동하지 않습니다 부정하는 곡절 (^)로 문자 클래스에 넣어 - '[] : 공간 [] [: 공간] []'경기 문자열을 부정하려고합니다. 대괄호 사이에있는 모든이 방식으로 인해 문자 클래스 둥지에, 그러나, 옵션 문자 목록에 밖으로 확장이라는 이름의 문자 클래스를 제외하고 선택적 단일 문자 목록으로 처리됩니다, 그것은 매우 가능성이 바깥 쪽 괄호가 있음을의 다음과 같이 해석되는 :

    그런 다음 당신에게 개별 조각을 찾기 위해 regex_substr 사용 REGEXP_REPLACE와 하나의 문자에 멀티 문자 구분을 변환하는 것이 더 쉬울 수 있습니다 :

    select regexp_substr(regexp_replace('Helloworld - test!'
                                       ,'[[:space:]]-[[:space:]]'
                                       ,chr(11))
                        ,'([^'||chr(11)||']*)('||chr(11)||'|$)'
                        ,1 -- Start here
                        ,2 -- return 1st, 2nd, 3rd, etc. match
                        ,null
                        ,1 -- return 1st sub exp
                        )
      from dual;
    

    이 코드에서 내가 먼저 변화 - (11) CHR 할 수 있습니다. 즉 대부분의 텍스트 문자열에 나타날 가능성이있는 ASCII 수직 탭 (VT) 문자입니다. 그런 다음 REGEXP_SUBSTR의 일치 표현식은 VT 문자 또는 라인의 한쪽 끝 다음에 모든 비 VT 문자와 일치합니다. 만 비 VT 문자 (첫 번째 표현식을) 반환됩니다.

  4. ==============================

    4.MT0의 대답에 약간의 개선. 동적 그것이 패턴 [^ 분리] +의 형식이 NULL리스트 요소를 처리하지 않는 널 (null) 처리를 사용 regexp_count 카운트 증명한다. 분할 쉼표 컬럼에 값을 구분 : 여기 있음에 더 많은 정보

    MT0의 대답에 약간의 개선. 동적 그것이 패턴 [^ 분리] +의 형식이 NULL리스트 요소를 처리하지 않는 널 (null) 처리를 사용 regexp_count 카운트 증명한다. 분할 쉼표 컬럼에 값을 구분 : 여기 있음에 더 많은 정보

    SQL> with tbl(str) as (
      2    select ' - Hello world - test-test! -  - test - ' from dual
      3  )
      4  SELECT LEVEL AS Occurrence,
      5         REGEXP_SUBSTR( str ,'(.*?)([[:space:]]-[[:space:]]|$)', 1, LEVEL, NULL, 1 ) AS split_value
      6  FROM   tbl
      7  CONNECT BY LEVEL <= regexp_count(str, '[[:space:]]-[[:space:]]')+1;
    
    OCCURRENCE SPLIT_VALUE
    ---------- ----------------------------------------
             1
             2 Hello world
             3 test-test!
             4
             5 test
             6
    
    6 rows selected.
    
    SQL>
    
  5. ==============================

    5.

    CREATE OR REPLACE FUNCTION field(i_string            VARCHAR2
                                    ,i_delimiter         VARCHAR2
                                    ,i_occurance         NUMBER
                                    ,i_return_number     NUMBER DEFAULT 0
                                    ,i_replace_delimiter VARCHAR2) RETURN VARCHAR2     IS
      -----------------------------------------------------------------------
      -- Function Name.......: FIELD
      -- Author..............: Dan Simson
      -- Date................: 05/06/2016 
      -- Description.........: This function is similar to the one I used from 
      --                       long ago by Prime Computer.  You can easily
      --                       parse a delimited string.
      -- Example.............: 
      --  String.............: This is a cool function
      --  Delimiter..........: ' '
      --  Occurance..........: 2
      --  Return Number......: 3
      --  Replace Delimiter..: '/'
      --  Return Value.......: is/a/cool
      --------------------------------------------------------------------------    ---                                    
      v_return_string  VARCHAR2(32767);
      n_start          NUMBER := i_occurance;
      v_delimiter      VARCHAR2(1);
      n_return_number  NUMBER := i_return_number;
      n_max_delimiters NUMBER := regexp_count(i_string, i_delimiter);
    BEGIN
      IF i_return_number > n_max_delimiters THEN
        n_return_number := n_max_delimiters + 1;
      END IF;
      FOR a IN 1 .. n_return_number LOOP
        v_return_string := v_return_string || v_delimiter || regexp_substr    (i_string, '[^' || i_delimiter || ']+', 1, n_start);
        n_start         := n_start + 1;
        v_delimiter     := nvl(i_replace_delimiter, i_delimiter);
      END LOOP;
      RETURN(v_return_string);
    END field;
    
    
    SELECT field('This is a cool function',' ',2,3,'/') FROM dual;
    
    SELECT regexp_substr('This is a cool function', '[^ ]+', 1, 1) Word1
          ,regexp_substr('This is a cool function', '[^ ]+', 1, 2) Word2
          ,regexp_substr('This is a cool function', '[^ ]+', 1, 3) Word3
          ,regexp_substr('This is a cool function', '[^ ]+', 1, 4) Word4
          ,regexp_substr('This is a cool function', '[^ ]+', 1, 5) Word5
      FROM dual;
    
  6. from https://stackoverflow.com/questions/31654411/split-string-by-space-and-character-as-delimiter-in-oracle-with-regexp-substr by cc-by-sa and MIT license