-2

The row I am trying to parse from is a series of string values separated only by spaces. Sample below: TX:123 SP:XapZNsyeS INST:456123

I need to use either regexp_substr or regexp_extract to return only values for the string that appears after "TX:" or "SP:", etc. So essentially an expression that only captures the string after a string (e.g. "TX:") and before a space (" ").

eps
  • 1

1 Answers1

0

Here's one way to split on 2 delimiters. This works on Oracle 12c as you included the Oracle regexp-substr tag. Using a with statement, first set up the original data, then split on a space or the end of the line, then break into name-value pairs.

WITH tbl_original_data(ID, str) AS (
  SELECT 1, 'TX:123 SP:XapZNsyeS INST:456123' FROM dual UNION ALL
  SELECT 2, 'MI:321 SP:MfeKLgkrJ INST:654321' FROM dual
),
tbl_split_on_space(ID, ELEMENT) AS (
SELECT ID,
       REGEXP_SUBSTR(str, '(.*?)( |$)', 1, LEVEL, NULL, 1) 
FROM tbl_original_data
CONNECT BY REGEXP_SUBSTR(str, '(.*?)( |$)', 1, LEVEL) IS NOT NULL 
  AND PRIOR ID = ID
  AND PRIOR SYS_GUID() IS NOT NULL        
)  
--SELECT * FROM tbl_split_on_space;   
SELECT ID,
       REGEXP_REPLACE(ELEMENT, '^(.*):.*', '\1') NAME,
       REGEXP_REPLACE(ELEMENT, '.*:(.*)$', '\1') VALUE
FROM tbl_split_on_space;

        ID NAME       VALUE     
---------- ---------- ----------
         1 TX         123       
         1 SP         XapZNsyeS 
         1 INST       456123    
         2 MI         321       
         2 SP         MfeKLgkrJ 
         2 INST       654321    

6 rows selected.

EDIT: Realizing this answer is a little more than was asked for, here's a simplified answer to return one element. Don't forget to allow for the ending of a space or the end of the line as well, in case you element is at the end of the line.

WITH tbl_original_data(ID, str) AS (
  SELECT 1, 'TX:123 SP:XapZNsyeS INST:456123' FROM dual
)
SELECT REGEXP_SUBSTR(str, '.*?TX:(.*)( |$)', 1, 1, NULL, 1) TX_VALUE
FROM tbl_original_data;

TX_VALUE
--------
123     
1 row selected.
Gary_W
  • 9,933
  • 1
  • 22
  • 40