我正在尝试提取一个字符串中的不同子字符串。对于每个用破折号(-)分隔的字符串,我都希望使用不同的字符串。
我尝试使用SUBSTR位置功能。由于有时第二个子字符串中有4个字符,因此它不起作用,因此,第三个子字符串不正确。
SELECT SUBSTR(STR, INSTR (STR, '-', -1)+ 1)
STR = F-123-A123-B12 or F-1234-A123-B12
我当时想我会使用一个正则表达式函数。我找不到一个。
答案 0 :(得分:7)
例如:
SQL> with test (col) as
2 (select 'F-123-A123-B12' from dual)
3 select regexp_substr(col, '\w+', 1, level) result
4 from test
5 connect by level <= regexp_count(col, '-') + 1;
RESULT
--------------
F
123
A123
B12
SQL>
答案 1 :(得分:1)
您不需要正则表达式。 INSTR
和SUBSTR
可以工作(并且速度更快):
Oracle设置:
CREATE TABLE test_data ( str ) AS
SELECT 'F-123-A123-B12' FROM DUAL UNION ALL
SELECT 'F-1234-A123-B12' FROM DUAL
查询1 :
SELECT SUBSTR( str, 1, delimiter1 - 1 ) AS substr1,
SUBSTR( str, delimiter1 + 1, delimiter2 - delimiter1 - 1 ) AS substr2,
SUBSTR( str, delimiter2 + 1, delimiter3 - delimiter2 - 1 ) AS substr3,
SUBSTR( str, delimiter3 + 1 ) AS substr4
FROM (
SELECT str,
INSTR( str, '-', 1, 1 ) AS delimiter1,
INSTR( str, '-', 1, 2 ) AS delimiter2,
INSTR( str, '-', 1, 3 ) AS delimiter3
FROM test_data
) s
输出:
SUBSTR1 | SUBSTR2 | SUBSTR3 | SUBSTR4 :------ | :------ | :------ | :------ F | 123 | A123 | B12 F | 1234 | A123 | B12
如果您确实想使用正则表达式,则不需要层次查询:
查询2 :
SELECT REGEXP_SUBSTR( str, '[^-]+', 1, 1 ) AS substr1,
REGEXP_SUBSTR( str, '[^-]+', 1, 2 ) AS substr2,
REGEXP_SUBSTR( str, '[^-]+', 1, 3 ) AS substr3,
REGEXP_SUBSTR( str, '[^-]+', 1, 4 ) AS substr4
FROM test_data
(输出为上述查询1。)
查询3
如果您不知道会有多少定界值并且想将它们全部解析为行,那么您 still 无需使用(慢速)正则表达式或分层查询,并且可以只需将递归子查询分解子句与简单的字符串函数一起使用(并且它与定界符之间的零宽度/ NULL
子字符串一起使用)
WITH substr_bounds ( str, idx, startidx, endidx ) AS (
SELECT str,
1,
1,
INSTR( str, '-', 1 )
FROM test_data
UNION ALL
SELECT str,
idx + 1,
endidx + 1,
INSTR( str, '-', endidx + 1 )
FROM substr_bounds
WHERE endidx > 0
)
SELECT str,
idx,
CASE
WHEN endidx = 0
THEN SUBSTR( str, startidx )
ELSE SUBSTR( str, startidx, endidx - startidx )
END AS substr
FROM substr_bounds
ORDER BY str, idx
输出:
STR | IDX | SUBSTR :-------------- | --: | :----- F-123-A123-B12 | 1 | F F-123-A123-B12 | 2 | 123 F-123-A123-B12 | 3 | A123 F-123-A123-B12 | 4 | B12 F-1234-A123-B12 | 1 | F F-1234-A123-B12 | 2 | 1234 F-1234-A123-B12 | 3 | A123 F-1234-A123-B12 | 4 | B12
db <>提琴here
答案 2 :(得分:0)
如果您的字符串可能包含NULL元素,请使用此格式进行处理(请注意,列表元素2为NULL),否则您可能会在错误的位置返回以下元素:
with test (col) as
(select 'F--A123-B12' from dual)
select regexp_substr(col, '(.*?)(-|$)', 1, level, null, 1) result
from test
connect by level <= regexp_count(col, '-') + 1;
RESULT
-----------
F
A123
B12
4 rows selected.