使用 regexp_substr 进行操作
Manipulating with regexp_substr
我有一个用于数据仓库目的的 ETL 任务,我需要在分隔符出现后提取字符串的第二部分,例如:'#'、'ý'、'-'。例如测试用例字符串:
'Tori 1#MHK-MahallaKingaveKD' 我应该只检索 'MHK'
'HPHelm2ýFFS-Tredddline' 我应该只检索 'FFS'
我已经尝试使用上面的案例:
TRIM(CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline', '#',1,1) > 0
THEN (REPLACE(
REGEXP_SUBSTR('HPHelm2ýFFS-Tredddline', '[^#]+', 1,2),
'#'
))
ELSE (CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline', '-',1,1) > 0
THEN (REPLACE(
REGEXP_SUBSTR('HPHelm2ýFFS-Tredddline', '[^-]+', 1,2),
'-'
))
ELSE (CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline','-') = 0 AND INSTR('HPHelm2ýFFS-Tredddline','ý') = 0 AND INSTR('HPHelm2ýFFS-Tredddline','#') = 0
THEN 'HPHelm2ýFFS-Tredddline'
ELSE (CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline','ý',1,1) > 0
THEN (REPLACE(
REGEXP_SUBSTR('HPHelm2ýFFS-Tredddline', '[^ý]+', 1,2),
'ý'
))
END)
END)
END)
END)
使用上面的代码我可以检索:
'Tori 1#MHK-MahallaKingaveKD' ====> 'MHK-MahallaKingaveKD'
'HPHelm2ýFFS-Tredddline' ====> 'FFS-Tredddline'
预期输出:
'Tori 1#MHK-MahallaKingaveKD' ====> 'MHK'
'HPHelm2ýFFS-Tredddline' ====> 'FFS'
所以我必须排除'-'和后面的字符串。
我想我应该修改 regexp_substr 模式,但似乎找不到明确的解决方案,因为在 when 语句中指定了 '-' 作为分隔符。
我建议检索第二次出现的 1+ 个字符,而不是分隔符字符:
regexp_substr(col, '[^#ý-]+', 1, 2)
此处,搜索从记录中的第一个字符 (1
) 开始,返回第二个字符 (2
)。
[^#ý-]+
模式匹配除 #
、ý
和 -
.
之外的一个或多个 (+
) 个字符
以下将为您提供所需的信息:
WITH cteData AS (SELECT 'Tori 1#MHK-MahallaKingaveKD' AS STRING FROM DUAL UNION ALL
SELECT 'HPHelm2ýFFS-Tredddline' FROM DUAL)
SELECT STRING, REGEXP_SUBSTR(STRING, '[#ý-](.*)[#ý-]', 1, 1, NULL, 1) AS SUB_STRING
FROM cteData;
分隔符组之间 .*
周围的括号使 .*
成为子表达式,参数列表中最后的 ,1
告诉 REGEXP_SUBSTR
给出您支持子表达式 #1 的值。由于正则表达式中只有一个子表达式,它会返回 .*
的值,这正是您要查找的值。
我有一个用于数据仓库目的的 ETL 任务,我需要在分隔符出现后提取字符串的第二部分,例如:'#'、'ý'、'-'。例如测试用例字符串:
'Tori 1#MHK-MahallaKingaveKD' 我应该只检索 'MHK'
'HPHelm2ýFFS-Tredddline' 我应该只检索 'FFS'
我已经尝试使用上面的案例:
TRIM(CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline', '#',1,1) > 0
THEN (REPLACE(
REGEXP_SUBSTR('HPHelm2ýFFS-Tredddline', '[^#]+', 1,2),
'#'
))
ELSE (CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline', '-',1,1) > 0
THEN (REPLACE(
REGEXP_SUBSTR('HPHelm2ýFFS-Tredddline', '[^-]+', 1,2),
'-'
))
ELSE (CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline','-') = 0 AND INSTR('HPHelm2ýFFS-Tredddline','ý') = 0 AND INSTR('HPHelm2ýFFS-Tredddline','#') = 0
THEN 'HPHelm2ýFFS-Tredddline'
ELSE (CASE
WHEN INSTR('HPHelm2ýFFS-Tredddline','ý',1,1) > 0
THEN (REPLACE(
REGEXP_SUBSTR('HPHelm2ýFFS-Tredddline', '[^ý]+', 1,2),
'ý'
))
END)
END)
END)
END)
使用上面的代码我可以检索:
'Tori 1#MHK-MahallaKingaveKD' ====> 'MHK-MahallaKingaveKD'
'HPHelm2ýFFS-Tredddline' ====> 'FFS-Tredddline'
预期输出:
'Tori 1#MHK-MahallaKingaveKD' ====> 'MHK'
'HPHelm2ýFFS-Tredddline' ====> 'FFS'
所以我必须排除'-'和后面的字符串。
我想我应该修改 regexp_substr 模式,但似乎找不到明确的解决方案,因为在 when 语句中指定了 '-' 作为分隔符。
我建议检索第二次出现的 1+ 个字符,而不是分隔符字符:
regexp_substr(col, '[^#ý-]+', 1, 2)
此处,搜索从记录中的第一个字符 (1
) 开始,返回第二个字符 (2
)。
[^#ý-]+
模式匹配除 #
、ý
和 -
.
+
) 个字符
以下将为您提供所需的信息:
WITH cteData AS (SELECT 'Tori 1#MHK-MahallaKingaveKD' AS STRING FROM DUAL UNION ALL
SELECT 'HPHelm2ýFFS-Tredddline' FROM DUAL)
SELECT STRING, REGEXP_SUBSTR(STRING, '[#ý-](.*)[#ý-]', 1, 1, NULL, 1) AS SUB_STRING
FROM cteData;
分隔符组之间 .*
周围的括号使 .*
成为子表达式,参数列表中最后的 ,1
告诉 REGEXP_SUBSTR
给出您支持子表达式 #1 的值。由于正则表达式中只有一个子表达式,它会返回 .*
的值,这正是您要查找的值。