使用REGEXP_SUBSTR获取键值对数据

时间:2015-03-02 21:44:54

标签: string oracle oracle12c

我的列数值低于

User_Id=446^User_Input=L307-60#/25" AP^^

我正在尝试根据指定的密钥获取每个单独的值。

  1. User_Id =之后的所有值,直到遇到^
  2. User_Input =之后的所有值,直到遇到^
  3. 我试过,到目前为止,我有这个,

    SELECT  LTRIM(REGEXP_SUBSTR('User_Id=446^User_Input=L307-60#/25" AP^'
              ,'[0-9]+',1,1),'^') User_Id 
    from dual
    

    如何获取User_Input的值?

    P.S:用户输入可以包含任何内容,例如',',*,%,包括字符串中间的^(即不作为分隔符)。

    任何帮助将不胜感激..

4 个答案:

答案 0 :(得分:1)

如果没有特别需要使用Regex,这样的东西会返回值。

WITH rslt AS (
SELECT 'User_Id=446^User_Input=L307-60#/25" AP^' val 
  FROM dual
)
SELECT LTRIM(SUBSTR(val
                   ,INSTR(val, '=', 1, 2) + 1
                   ,INSTR(val, '^', 1, 2) - (INSTR(val, '=', 1, 2) + 1)))
  FROM rslt;

当然,如果您不能保证不存在任何有效文本字符的插入符号,则可能会返回部分结果。

答案 1 :(得分:1)

使用枯燥的旧INSTR可以很容易地解决这个问题,以计算KEY和VALUE字符串的起点和终点的偏移量。

诀窍是使用可选的occurrence参数来识别每个=的正确实例。由于输入可能包含不作为分隔符的插入符号,因此我们需要使用否定位置来标识最后一个^

with cte as  (
  select kv
         , instr(kv, '=', 1, 1)+1 as k_st  -- first occurrence 
         , instr(kv, '^', 1) as k_end
         , instr(kv, '=', 1, 2)+1 as v_st  -- second occurrence 
         , instr(kv, '^', -1) as v_end     -- counting from back
  from t23
  )
select substr(kv, k_st, k_end - k_st) as user_id
       , substr(kv, v_st, v_end - v_st) as user_input
from cte
/

这是requisite SQL Fiddle to prove it works。我认为它比任何正则表达式更容易理解。

答案 2 :(得分:0)

假设您将始终拥有' User_Id ='和' User_Input ='在你的字符串中,我会使用字符组方法来解析

使用起始锚点^和结束锚点$。查找'User_Id=''User_Input='

将您要搜索的值与字符组相关联。

    SCOTT@dev> 
  1  SELECT REGEXP_SUBSTR('User_Id=446^User_Input=L307-60#/25" AP^','^User_Id=(.*\^)User_Input=(.*\^)$',1, 1, NULL, 1) User_Id
  2* FROM dual
SCOTT@dev> /

USER
====
446^


SCOTT@dev> 
  1  SELECT REGEXP_SUBSTR('User_Id=446^User_Input=L307-60#/25" AP^','^User_Id=(.*\^)User_Input=(.*\^)$',1, 1, NULL, 2) User_Input
  2* FROM dual
SCOTT@dev> /

USER_INPUT
================
L307-60#/25" AP^

SCOTT@dev> 

答案 3 :(得分:0)

我的朋友得到了这个答案..看起来很简单,效果很好......

SELECT
regexp_replace('User_Id=446^User_Input=L307-60#/25" AP^^', '.*User_Id=([^\^]+).*', '\1') User_Id,
regexp_replace('User_Id=446^User_Input=L307-60#/25" AP^^', '.*User_Input=(.*)[\^]$', '\1') User_Input
FROM dual

发布此处以防万一你觉得有趣......