我使用了case语句,但仍然无法正常工作。我该怎么解决。
d m k
3 33 2863311531
5 34 3435973837
6 34 2863311531
9 35 3817748708
10 35 3435973837
11 35 3123612579
12 35 2863311531
13 35 2643056798
15 35 2290649225
17 36 4042322161
查询结果:
WITH tst
AS
(
SELECT '639 - xadfa dfdsa euwere (15-30Min)' str FROM DUAL
UNION
SELECT 'AB/NCDSDFsd - 218' FROM DUAL
UNION
SELECT '141 - Uxsdfasd Zebasdased ABC3' FROM DUAL
)
SELECT
str,
CASE
WHEN LENGTH(TRIM(SUBSTR(TRIM(REGEXP_REPLACE(str, '([^[:digit:] ])', '')),-3,3))) = 3
THEN TRIM(SUBSTR(TRIM(REGEXP_REPLACE(str, '([^[:digit:] ])', '')),-3,3))
ELSE
CASE
WHEN LENGTH(TRIM(SUBSTR(TRIM(REGEXP_REPLACE(str, '([^[:digit:] ])', '')),1,3))) = 3
THEN TRIM(SUBSTR(TRIM(REGEXP_REPLACE(str, '([^[:digit:] ])', '')),1,3))
ELSE NULL
END
END num_val
FROM tst;
如果字符串以3个连续数字集开头,那么我需要第一个3位数字集。如果字符串以字母开头,那么我需要在字符串末尾设置3位数字。 预期输出:
STR NUM_VAL
--------------------------------------------
141 - Uxsdfasd Zebasdased ABC3 141
639 - xadfa dfdsa euwere (15-30Min) 530
AB/NCDSDFsd - 218 218
答案 0 :(得分:2)
重新设计的问题可以解决,例如,如下:
WITH tst
AS
(
SELECT '639 - xadfa dfdsa euwere (15-30Min)' str FROM DUAL UNION ALL
SELECT 'AB/NCDSDFsd - 218' FROM DUAL UNION ALL
SELECT 'dsafas 123 COMP - 751' FROM DUAL UNION ALL
SELECT '141 - Uxsdfasd Zebasdased ABC3' FROM DUAL
)
select str, regexp_substr(str, '(^\d{3}|\d{3}$)') as num
from tst;
STR NUM
----------------------------------- -------------------
639 - xadfa dfdsa euwere (15-30Min) 639
AB/NCDSDFsd - 218 218
dsafas 123 COMP - 751 751
141 - Uxsdfasd Zebasdased ABC3 141
正则表达式是一个交替。 ^
和$
是锚点-它们要求片段分别位于输入字符串的开头和结尾。 ( ... | ... )
表示找到第一个替代方案,如果找不到,则找到第二个替代方案。 \d{3}
恰好表示3位数字。
答案 1 :(得分:0)
据我所知,这是一个解决方案:
WITH tst
AS
(
SELECT '639 - xadfa dfdsa 456 euwere (15-30Min)' str FROM DUAL
UNION
SELECT 'AB/NCDSDFsd - 218' FROM DUAL
UNION
SELECT '141 - Uxsdfasd Zebasdased ABC3' FROM DUAL
)
select str,
regexp_substr(str, '[[:digit:]]{3}', 1, regexp_count(str, '[[:digit:]]{3}')) as num_val
from tst;
STR NUM_VAL
------------------------------------------- -----------
141 - Uxsdfasd Zebasdased ABC3 141
639 - xadfa dfdsa 456 euwere (15-30Min) 456
AB/NCDSDFsd - 218 218
答案 2 :(得分:0)
在数字和末尾锚点之间使用非贪婪量词,或者使用....反向功能
我使用非贪婪量词方法(第23行),但是它似乎主要是因为第一个量词是贪心。
我使用锚来匹配整个字符串。我将匹配项“非行字符”放在子表达式中,并在字符串的末尾使用非贪婪量词*? (零个或多个)。
非贪婪量词在Oracle 12.1(我正在使用)中并不总是有效。
方案b只是使用反向函数2x(第24行)。
SCOTT@db>WITH tst AS (
2 SELECT
3 '141 - Uxsdfasd Zebasdased ABC3 141 639 - xadfa dfdsa euwere (15-30Min) 639 AB/NCDSDFsd - 2184 4 5' smple
4 FROM
5 dual
6 UNION ALL
7 SELECT
8 '639 - xadfa dfdsa euwere (15-30Min)'
9 FROM
10 dual
11 UNION ALL
12 SELECT
13 'AB/NCDSDFsd - 218'
14 FROM
15 dual
16 UNION ALL
17 SELECT
18 '141 - Uxsdfasd Zebasdased ABC3'
19 FROM
20 dual
21 ) SELECT
22 smple,
23 regexp_substr(smple,'^(.)*(\d{3})(.)*?$',1,1,NULL,2) nongreedy,
24 reverse(regexp_substr(reverse(smple),'(\d{3})',1,1,NULL,1) ) rev_fun
25 FROM
26 tst;
SMPLE NONGREEDY REV_FUN
141 - Uxsdfasd Zebasdased ABC3 141 141
141 - Uxsdfasd Zebasdased ABC3 141 639 - xadfa dfdsa euwere (15-30Min) 639 AB/NCDSDFsd - 2184 4 5 184 184
639 - xadfa dfdsa euwere (15-30Min) 639 639
AB/NCDSDFsd - 218 218 218