Home > OS >  Oracle Regexp_substr to return a value from a yaml string
Oracle Regexp_substr to return a value from a yaml string

Time:01-24

I am trying to parse the yaml string to a column in SQL.

I have a yaml string in one of the columns like

country_cd:GB
postal_town_city:London
zip:CT11 A1Cr

I have to write a query to pass the key and get a value. When I pass 'country_cd', I want to receive 'GB'.

I have tried the below script but it is returning 'country_cd:G'. What am I doing incorrectly ?

 select trim(regexp_substr('---
 country_cd:GB
 postal_town_city:London
 zip:CT11 A1Cr', '\n?'||'postal_town_city'||'*[:=] *(. ?) *\n?', 1, 1, 'i')) from dual ; 

CodePudding user response:

You can use REGEXP_SUBSTR with the m match parameter to parse the string as separate lines:

SELECT REGEXP_SUBSTR(yaml, '^country_cd:(.*)$', 1, 1, 'm', 1) AS value
FROM   table_name;

Which, for the sample data:

CREATE TABLE table_name (yaml) AS
SELECT 'country_cd:GB
postal_town_city:London
zip:CT11 A1Cr' FROM DUAL;

Outputs:

VALUE
GB

or, you can split the string using simple string functions (which are often quicker than using regular expressions) and then filter for the correct key:

WITH lines (yaml, line_start, separator_pos, line_end) AS (
  SELECT yaml,
         1,
         INSTR(yaml, ':', 1),
         INSTR(yaml, CHR(10), 1)
  FROM   table_name
UNION ALL
  SELECT yaml,
         line_end   1,
         INSTR(yaml, ':', line_end   1),
         INSTR(yaml, CHR(10), line_end   1)
  FROM   lines
  WHERE  line_end > 0
)
SELECT SUBSTR(yaml, line_start, separator_pos - line_start) AS key,
       CASE line_end
       WHEN 0
       THEN SUBSTR(yaml, separator_pos   1)
       ELSE SUBSTR(yaml, separator_pos   1, line_end - separator_pos)
       END AS value
FROM   lines
WHERE  SUBSTR(yaml, line_start, separator_pos - line_start) = 'country_cd'

Which outputs:

KEY VALUE
country_cd GB

db<>fiddle here

CodePudding user response:

Using REGEXP_SUBSTR with a capture group, we can try:

SELECT yaml,
       REGEXP_SUBSTR(yaml_col, '(^|\s)country_cd:(\S )', 1, 1, NULL, 2) AS country_cd
FROM yourTable;

Here is regex demo.

  •  Tags:  
  • Related