OracleRegExp,如果字符串以数字开头,请在起始处查找长度为3的数字。否则,在末尾查找长度为3位的数字
我使用了案例陈述,但仍然不起作用。我怎样才能解决这个问题OracleRegExp,如果字符串以数字开头,请在起始处查找长度为3的数字。否则,在末尾查找长度为3位的数字,oracle,regexp-replace,Oracle,Regexp Replace,我使用了案例陈述,但仍然不起作用。我怎样才能解决这个问题 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 LENGT
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;
查询结果:
STR NUM_VAL
--------------------------------------------
141 - Uxsdfasd Zebasdased ABC3 141
639 - xadfa dfdsa euwere (15-30Min) 530
AB/NCDSDFsd - 218 218
如果字符串以3个连续的数字集开始,那么我需要前3个数字集。如果字符串以字母开头,那么我需要在字符串末尾设置3位数字。 预期产出:
STR NUM_VAL
--------------------------------------------
141 - Uxsdfasd Zebasdased ABC3 141
639 - xadfa dfdsa euwere (15-30Min) 639
AB/NCDSDFsd - 218 218
据我所知,这将是一个解决方案:
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
在数字和结束锚之间使用非贪婪量词或…反向功能 我使用了一种非贪婪的量词方法(第23行),但它似乎起作用主要是因为第一个量词是贪婪的 我使用锚来匹配整个字符串。我将匹配项“non-end-of-line character”放在子表达式中,并在字符串的末尾使用非贪婪量词*?(零或更多) 非贪婪量词在Oracle 12.1(我正在使用)中并不总是有效 方案b仅使用反向功能2x(第24行)
例如,可以通过以下方式解决重新制定的问题:
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位数字。你能编辑你的问题来解释你想做什么吗?标题是spunds,就像你想要字符串中最后一组三个连续的数字一样,也许?从'141-some stuff-3920-blah'
返回什么?141是三位数字,3920是四位数字,那么返回141?或返回920(输入中三个连续数字的最后一个序列)?或者别的什么?如果字符串以3个连续的数字集开始,那么我需要第一个3个数字集。如果字符串以字母开头,那么我需要在字符串末尾设置3位数字。总是期待意外的结果!如果字符串以特殊字符开头怎么办?以字母开头但以4位数字结尾?没有号码吗?是空字符串吗?提供一些要测试的异常,以及如何处理这些异常。正确的解决方案必须处理好这一切。不要等到代码投入生产后才发现惊喜!OP需要澄清要求。您提供的解决方案将从输入中返回394'141 something 39458 something'
-字符串中最后出现的三位数不太可能是'394'
。如果有的话,那就是'458'
。谢谢@mathguy。。这看起来是一个完美的解决方案。我真的很感谢你之前的评论,是的,我同意解决方案应该处理所有情况。
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