【问题标题】:How to get number between special character in oracle如何在oracle中获取特殊字符之间的数字
【发布时间】:2018-07-10 04:27:51
【问题描述】:

你能帮助在 oracle 中获得以下输出吗

File_20170902_Name.txt
File200_Name_20170902_1.txt
File400_20170902_Name_1.txt
File1_name_20170902.txt

我期待像

这样的输出
20170902
20170902
20170902
20170902

提前致谢!!

【问题讨论】:

标签: sql oracle oracle11g


【解决方案1】:

假设文件名中的所有 8 位数字都是日期,并且前面是 _,后面是 _.txt,您可以使用

select REGEXP_SUBSTR(files,'_(\d{8})(_|.txt)',1,1,NULL,1) as dt FROM t;

Demo

但有些时间数字字符会变成 6 (YYMMDD) 字符

这将匹配__.txt之间的6到8个字符的序列

REGEXP_SUBSTR(files,'_((\d{6,8}))(_|)',1,1,NULL,1)

Demo2

但是,这不是一个全面的正则表达式来匹配日期。即它可以匹配像20189999180000这样的数字,如果它们是文件名的一部分。如果您只想检测日期,则可能必须将它们与此处指定的方法结合使用:Valid Date Checks in Oracle

【讨论】:

  • 谢谢 kaushik。但是有些时间数字字符会变成 6 (YYMMDD) 字符。有办法处理这种情况吗?
  • 此查询给出以下结果。选择 REGEXP_SUBSTR('File_20170902_Name.txt','_((\d{6}|\d{8}))(_|)',1,1,NULL,1) from dual; O/P: 201709 但我的期望是“20170902”。谢谢!!
  • @user3444185 : 现在检查一下我已经修改了
【解决方案2】:

试试这个演示:http://sqlfiddle.com/#!4/c361c/4

select
 regexp_replace(str,'.*(\d{8}).*','\1') as x
from table1

|        X |
|----------|
| 20170902 |
| 20170902 |
| 20170902 |
| 20170902 |

【讨论】:

    【解决方案3】:

    试试这个

    create table tst (x varchar2(30));
    insert into tst values ('File_20170902_Name.txt');
    insert into tst values ('File200_Name_20170902_1.txt');
    insert into tst values ('File400_20170902_Name_1.txt');
    insert into tst values ('File1_name_20170902.txt');
    
    Select x,       
          case 
              when substr(x, REGEXP_INSTR(x, '[^a-z|A-Z|0-9]') + 1, 1) between chr(48) and chr(57) Then 
                substr(x, REGEXP_INSTR(x, '[^a-z|A-Z|0-9]') + 1, REGEXP_INSTR(x, '[^a-z|A-Z|0-9]', 1, 2) - REGEXP_INSTR(x, '[^a-z|A-Z|0-9]') - 1) 
              else substr(x, REGEXP_INSTR(x, '[^a-z|A-Z|0-9]', 1, 2) + 1, REGEXP_INSTR(x, '[^a-z|A-Z|0-9]', 1, 3) - REGEXP_INSTR(x, '[^a-z|A-Z|0-9]', 1, 2) - 1) 
          end as t      
    From tst  
    

    注意:如果数字以 File_name_test_20170902.txt 等 2 个以上特殊字符开头,则此查询不支持

    【讨论】:

      【解决方案4】:

      以下两者的工作方式大致相同 - 使用正则表达式进行基本选择,然后使用第二次调用 REGEXP_SUBSTR 或使用“普通”字符串函数来摆脱分隔符。我更喜欢对REGEXP_SUBSTR 的嵌套调用,而不是使用TRANSLATEREPLACE,但你可以选择:

      REGEXP_SUBSTR的嵌套调用:

      WITH cteFiles AS (SELECT 'File_20170902_Name.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File200_Name_20170902_1.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File400_20170902_Name_1.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File1_name_20170902.txt' AS FILENAME FROM DUAL)
      SELECT FILENAME, REGEXP_SUBSTR(REGEXP_SUBSTR(FILENAME, '_[0-9]+[_.]'), '[^_.]+') AS FINAL_NUMS
        FROM cteFiles;
      

      使用REPLACE

      WITH cteFiles AS (SELECT 'File_20170902_Name.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File200_Name_20170902_1.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File400_20170902_Name_1.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File1_name_20170902.txt' AS FILENAME FROM DUAL)
      SELECT FILENAME, REPLACE(REPLACE(REGEXP_SUBSTR(FILENAME, '_[0-9]+[_.]'), '_', NULL), '.', NULL) AS FINAL_NUMS
        FROM cteFiles;
      

      使用TRANSLATE

      WITH cteFiles AS (SELECT 'File_20170902_Name.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File200_Name_20170902_1.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File400_20170902_Name_1.txt' AS FILENAME FROM DUAL UNION ALL
                        SELECT 'File1_name_20170902.txt' AS FILENAME FROM DUAL)
      SELECT FILENAME, TRANSLATE(REGEXP_SUBSTR(FILENAME, '_[0-9]+[_.]'), '0123456789_.', '0123456789') AS FINAL_NUMS
        FROM cteFiles;
      

      SQLFiddle here

      祝你好运。

      【讨论】:

        猜你喜欢
        • 2021-01-14
        • 2013-03-16
        • 1970-01-01
        • 2016-02-12
        • 2019-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-16
        相关资源
        最近更新 更多