【问题标题】:Oracle regexp_substr to extract dataOracle regexp_substr 提取数据
【发布时间】:2020-10-10 18:39:47
【问题描述】:

我正在尝试从字符串中提取下载和上传速度数字,无法实现,请帮助

输入字符串:My ADSL 14Mbps/2M speed

预期输出:

Download_speed = 14
Upload_speed = 2

我的 SQL

SELECT regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+') donwload_speed
      ,regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+$') upload_speed
  FROM dual 

输出来自上面的 SQL

download_speed = My Fiber 14Mbps
upload_speed = 2M speed

【问题讨论】:

  • 提示:在发布之前,请对您的数据进行选择,并确保您发布的示例数据从一开始就包含所有可能的格式示例。然后,尤其是使用正则表达式,确保您可以以满足所有示例的方式描述您需要以纯文本提取的内容。即“提取字符串 Mbps 之前的数字(不区分大小写)但在斜线之前作为下载速度。提取斜线之后和始终大写 M 之前的数字,后跟一个空格作为下载速度”。然后将其转换为正则表达式。期待意外!句柄未找到号码。

标签: sql regex oracle regexp-substr


【解决方案1】:

你可以使用

SELECT regexp_substr('My ADSL 14Mbps/2M speed','(\d+)Mbps/\d+M', 1, 1, NULL, 1) donwload_speed
      ,regexp_substr('My ADSL 14Mbps/2M speed','\d+Mbps/(\d+)M', 1, 1, NULL, 1) upload_speed
  FROM dual 

查看SQLFiddle

(\d+)Mbps/\d+M 模式匹配并捕获到组 1 任何一个或多个数字,然后是 Mbps/,然后是 1+ 数字,然后是 M(借助最后一个 1 参数提取组值)。

\d+Mbps/(\d+)M 模式匹配任何一位或多位数字,然后是 Mbps/,然后是 1+ 位被捕获到第 1 组,然后是 M

参见regex #1 demoregex #2 demo

【讨论】:

  • 您好,感谢您的 sql,如果字符串仅在一个地方有数字,则上述 SQL 工作正常,但假设 SQL 在其他地方有一些数字,则它正在加入,示例输入文本是“我的 ADSL 2M(200) 音量 14Mbps/2M 速度阈值 0M”,我只需要 14 和 2 个在单词中带有正斜杠的数字
  • @user2907940 您有机会查看我更新的解决方案吗?如果您需要更多帮助,请提供反馈。
  • 您好,我尝试在 SQL 上面执行,得到错误太多函数参数 - oracle 版本 Oracle 数据库 10g
  • @user2907940 它seems to be fine,它允许这些参数。
【解决方案2】:

我想如果你只想得到数字,那么我会这样做:

SQL> col download_speed for 999999 heading "download_speed"
SQL> col upload_speed for 999999 heading "upload_speed"
SQL> SELECT regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+'),'[^0-9]', '') download_speed
  ,regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+$'), '[^0-9]', '') upload_speed FROM dual;

do u
-- -
14 2

但是,如果您想将列转换为行,正如您在预期结果中显示的那样,我会这样做:

    select *
from (
SELECT regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+'),'[^0-9]', '') download_speed
      ,regexp_replace(regexp_substr('My ADSL 14Mbps/2M speed','[^\/]+$'), '[^0-9]', '') upload_speed
  FROM dual
) unpivot include nulls ( val for col in (download_speed,upload_speed) );

COL            VA
-------------- --
DOWNLOAD_SPEED 14
UPLOAD_SPEED   2

您可以更改所需标签的 COL 和 VA 的值

【讨论】:

  • 您好,感谢您的 sql,如果字符串仅在一个地方有数字,则上述 SQL 工作正常,但假设 SQL 在其他地方有一些数字,则它正在加入,示例输入文本是“我的 ADSL 2M(200) 音量 14Mbps/2M 速度阈值 0M”,我只需要 14 和 2 个在单词中带有正斜杠的数字
【解决方案3】:

您只需要提取从位置1开始的数字序列(\d+)

  • 用于下载数字序列的出现1
  • 用于上传出现2 的数字序列。

下面是 SQL 代码:

SQL> SELECT
  2  'download_speed = ' || regexp_substr('My ADSL 14Mbps/2M speed','(\d+)', 1, 1)
  3  ||
  4  ' upload_speed = ' || regexp_substr('My ADSL 14Mbps/2M speed','(\d+)', 1 ,2)
  5  as output
  6  from dual;

OUTPUT
----------------------------------------
download_speed = 14 upload_speed = 2

SQL> 

【讨论】:

  • 您好,感谢您的 sql,如果字符串仅在一个地方有数字,则上述 SQL 工作正常,但假设 SQL 在其他地方有数字,则它正在加入,示例输入文本是“我的 ADSL 2M(200) 音量 14Mbps/2M 速度阈值 0M”,我只需要 14 和 2 个在单词中带有正斜杠的数字
  • 请编辑您的问题以添加 all 输入数据和 all 预期输出。
  • 或者最好用 all 输入和 all 预期输出提出一个新问题。
【解决方案4】:

一种选择是使用REGEXP_REPLACE(),它使用replace_string \2 作为第三个参数搜索数字字符:

SELECT REGEXP_REPLACE(str,'(.* )(\d+)(.*)','\2') AS download_speed, 
       REGEXP_REPLACE(str,'(.*\/)(\d+)(.*)','\2') AS upload_speed
  FROM tab

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 2018-07-05
    • 2012-06-26
    • 2021-12-18
    • 2016-05-22
    • 2014-12-10
    • 2014-08-18
    • 2014-05-28
    相关资源
    最近更新 更多