Oracle 11g은 정규식으로 일치하는 모든 항목을 가져옵니다.
저는 Oracle 11g을 사용하고 있으며 REGEXP_SUBSTR을 사용하여 주어진 패턴에 대한 모든 발생 항목을 일치시키고 싶습니다.예를들면
SELECT
REGEXP_SUBSTR('Txa233141b Ta233141 Ta233142 Ta233147 Ta233148',
'(^|\s)[A-Za-z]{2}[0-9]{5,}(\s|$)') "REGEXP_SUBSTR"
FROM DUAL;
첫 번째 일치 Ta233141만 반환하지만 정규식과 일치하는 다른 항목, 즉 Ta233142 Ta233147 Ta233148을 반환합니다.
REGEXP_SUBSR은 하나의 값만 반환합니다.문자열을 유사 테이블로 변환한 다음 일치 항목을 쿼리할 수 있습니다.XML 기반의 방법이 있지만, 소스 문자열이 하나만 있으면 연결 방식을 사용할 수 있습니다.
SELECT REGEXP_SUBSTR(str, '[^ ]+', 1, LEVEL) AS substr
FROM (
SELECT 'Txa233141b Ta233141 Ta233142 Ta233147 Ta233148' AS str FROM DUAL
)
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(str, '[^ ]+')) + 1;
제공:
SUBSTR
--------------------
Txa233141b
Ta233141
Ta233142
Ta233147
Ta233148
원래 패턴의 약간 단순한 버전으로 필터링할 수 있습니다.
SELECT substr
FROM (
SELECT REGEXP_SUBSTR(str, '[^ ]+', 1, LEVEL) AS substr
FROM (
SELECT 'Txa233141b Ta233141 Ta233142 Ta233147 Ta233148' AS str
FROM DUAL
)
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(str, '[^ ]+')) + 1
)
WHERE REGEXP_LIKE(substr, '^[A-Za-z]{2}[0-9]{5,}$');
SUBSTR
--------------------
Ta233141
Ta233142
Ta233147
Ta233148
그다지 예쁘지는 않지만, 한 분야에 여러 가지 가치가 있는 것은 아닙니다.
조금 늦었지만 기본적으로 같은 것이 필요했고 좋은 스니펫을 찾을 수 없었습니다.표의 자유 텍스트 열에서 몇 가지 용어를 검색하여 수집해야 했습니다.이것이 다른 사람에게 유용할 수도 있기 때문에 이 질문에 기반한 버전을 포함했습니다.REGEXP_SUBSR은 하나의 값만 반환하지만 Oracle은 지정된 문자열에 얼마나 많은 일치 항목이 있는지 알려주는 REGEXP_COUNT도 제공하므로 이 값에 다음과 같이 인덱스 목록을 결합하여 각 항목을 선택할 수 있습니다(이 쿼리의 예제를 일부 'source_table'의 자유 텍스트로 사용).
DEFINE MATCH_EXP = "'(^|\s)[A-Za-z]{2}[0-9]{5,}'"
WITH source_table
-- Represents some DB table with a 'free_text' column to be checked.
AS ( ( SELECT 'Txa233141 Ta233141 Ta232 Ta233142 Ta233141 Ta233148'
AS free_text FROM dual )
UNION ( SELECT 'Other stuff PH33399 mixed in OS4456908843 this line'
AS free_text FROM dual )
)
, source
-- For some table, select rows of free text and add the number of matches
-- in the line.
AS ( SELECT cnt
, free_text
FROM ( SELECT RegExp_Count(free_text, &MATCH_EXP) AS cnt
, free_text
FROM source_table )
WHERE cnt > 0 )
, iota
-- Index generator
AS ( SELECT RowNum AS idx
FROM dual
CONNECT BY RowNum <= ( SELECT Max(cnt) FROM source ) )
-- Extract the unique 'cnt' matches from each line of 'free_text'.
SELECT UNIQUE
RegExp_SubStr(s.free_text, &MATCH_EXP, 1, i.idx) AS result
FROM source s
JOIN iota i
ON ( i.idx <= s.cnt )
ORDER BY result ASC
;
선택한 행 목록에서 작업할 수 있는 장점이 있으며, 매우 느릴 수 있으므로 연결 기준을 최소로 사용합니다.
루프를 통해 모든 값을 반환하는 기능을 추가하는 것은 어떻습니까?
create or replace function regexp_substr_mr (
p_data clob,
p_re varchar
)
return varchar as
v_cnt number;
v_results varchar(4000);
begin
v_cnt := regexp_count(p_data, p_re, 1,'m');
if v_cnt < 25 then
for i in 1..v_cnt loop
v_results := v_results || regexp_substr(p_data,p_re,1,i,'m') || chr(13) || chr(10);
end loop;
else
v_results := 'WARNING more than 25 matches found';
end if;
return v_results;
end;
그런 다음 선택 쿼리의 일부로 함수를 호출합니다.
다중 회선 소스 지원 및 보다 신속한 실행을 위해 @Alex Pool 답변 수정합니다.
with templates as (select '\w+' regexp from dual)
select
regexp_substr(str, templates.regexp, 1, level) substr
from (
select 1 id, 'Txa233141b Ta233141 Ta233142 Ta233147 Ta233148' as str from dual
union
select 2 id, '2 22222222222222Ta233141 2Ta233142 2Ta233147' as str from dual
union
select 3 id, '3Txa233141b 3Ta233141 3Ta233142' as str from dual
)
join templates on 1 = 1
connect by
id = connect_by_root id
and regexp_instr(str, templates.regexp, 1, level) > 0
order by id, level
소스 라인:
ID STR
-- ----------------------------------------------
1 Txa233141b Ta233141 Ta233142 Ta233147 Ta233148
2 2 22222222222222Ta233141 2Ta233142 2Ta233147
3 3Txa233141b 3Ta233141 3Ta233142
결과:
Txa233141b
Ta233141
Ta233142
Ta233147
Ta233148
2
22222222222222Ta233141
2Ta233142
2Ta233147
3Txa233141b
3Ta233141
3Ta233142
@David E를 기준으로 합니다.벨리예프 답변입니다. 다중 행 입력에 대한 쿼리입니다.아래의 질문이 당신에게 도움이 된다면, 원래의 답변을 투표로 올리는 것을 고려해보세요.
SELECT SUBSTR
FROM (WITH TEMPLATES AS (SELECT '\w+' REGEXP FROM DUAL)
SELECT ID,
CONNECT_BY_ROOT ID CBR,
LEVEL LVL,
REGEXP_SUBSTR(STR, TEMPLATES.REGEXP, 1, LEVEL) SUBSTR
FROM (SELECT 1 ID,
'Txa233141b Ta233141 Ta233142 Ta233147 Ta233148' AS STR
FROM DUAL
UNION
SELECT 2 ID,
'2 22222222222222Ta233141 2Ta233142 2Ta233147' AS STR
FROM DUAL
UNION
SELECT 3 ID,
'3Txa233141b 3Ta233141 3Ta233142' AS STR
FROM DUAL)
JOIN TEMPLATES
ON 1 = 1
CONNECT BY REGEXP_INSTR(STR, TEMPLATES.REGEXP, 1, LEVEL) > 0)
WHERE ID = CBR
GROUP BY ID,
CBR,
LVL,
SUBSTR
ORDER BY ID,
LVL;
입력:
ID STR== ==============================================1 Txa233141b Ta233141Ta233142Ta233147Ta23314822 222222222222Ta233141 2Ta233142 2Ta23314733Txa233141b 3Ta233141 3Ta233142
출력:
서브스트======================Txa233141bTa233141Ta233142Ta233147Ta2331482222222222222Ta2331412Ta2331422Ta2331473Txa233141b3Ta2331413Ta233142
SELECT
LISTAGG(REGEXP_SUBSTR('Txa233141b Ta233141 Ta233142 Ta233147 Ta233148', '(^|\s)[A-Z]{2}[0-9]{5,}',1,level)
) WITHIN GROUP(ORDER BY 1)
AS REGEXP_SUBSTR
FROM DUAL
CONNECT BY level<=regexp_count('Txa233141b Ta233141 Ta233142 Ta233147 Ta233148','(^|\s)[A-Z]{2}[0-9]{5,}')
;
아래는 당신의 질문에 대한 쉬운 해결책입니다.
SELECT REGEXP_SUBSTR('Txa233141b Ta233141 Ta233142 Ta233147 Ta233148',
'([a-zA-Z0-9]+\s?){1,}') "REGEXP_SUBSTR"
FROM DUAL;
언급URL : https://stackoverflow.com/questions/17596363/oracle-11g-get-all-matched-occurrences-by-a-regular-expression
'programing' 카테고리의 다른 글
데이터베이스 열의 비트 플래그에 대한 단점은 무엇입니까? (0) | 2023.07.21 |
---|---|
오래된 값을 사용하는 트랜잭션 내에서 실행되는 스프링 네이티브 쿼리 (0) | 2023.07.21 |
봄 구름과 유레카가 있는 리본: java.lang.잘못된 상태 예외:Samarths-MacBook-Pro.local에 사용할 수 있는 인스턴스가 없습니다. (0) | 2023.07.21 |
Panda DataFrame에 메타 정보/메타데이터 추가 (0) | 2023.07.21 |
Python에서 오류가 없을 때까지 시도합니다. (0) | 2023.07.21 |