Oracle 正则表达式,如果字符串以数字开头,则在开头查找长度为 3 的数字。否则,在末尾找到 3 位数长度的数字

Oracle regexp, Find a number length of 3 in the beginnning, if the string begins with a number. Else, find number with 3 digit length at the end

我已经使用了 case 语句,但仍然不起作用。我该如何解决这个问题。

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 行)。

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

重新制定的问题可以解决,例如,如下:

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 位数字。