使用REGEXP_SUBSTR获取键值对数据

Using REGEXP_SUBSTR to get key-value pair data

我有一列包含以下值,

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

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

  1. User_Id=之后的所有值直到遇到^
  2. User_Input=之后的所有值直到遇到^

我试过了,到目前为止我有这个,

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:用户输入可以包含任何内容,如 ',", *,%,包括字符串中间的 ^(即,不作为分隔符)。

任何帮助将不胜感激..

如果没有特别需要使用正则表达式,像这样的东西return是值。

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;

当然,如果您不能保证不会有任何插入符是有效的文本字符,这可能会 return 部分结果。

假设您的字符串中始终包含 '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> 

这可以很容易地解决,使用无聊的旧 INSTR 来计算 KEY 和 VALUE 字符串的起点和终点的偏移量。

诀窍是使用可选的出现参数来识别 = 的每个正确实例。因为输入可以包含不打算用作分隔符的插入符,所以我们需要使用负数位置来标识最后一个 ^.

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。我认为它比任何等效的正则表达式更容易理解。

从我的一个朋友那里得到了这个答案。看起来很简单,但效果很好...

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

张贴在这里以防你们中的任何人觉得它有趣..