【问题标题】:Oracle 18c XE- How to split string into numbersOracle 18c XE-如何将字符串拆分为数字
【发布时间】:2021-02-01 08:25:28
【问题描述】:

我正在尝试将字符串拆分为数字。字符串如下所示:

POINT(-122.419956922531 37.7647100858191)

我想删除“点”和括号,只得到数字。我试过这个(下面的代码)。尽管它在表格中看起来不错,但我仍然无法将结果转换为数字:

select 
   REGEXP_SUBSTR(geom_, '(\S*)' ) as longi,
    REGEXP_SUBSTR(geom_, '(\S*)[^()]',1,2) as atti    
from 
   (select 
      a.*,
      REGEXP_SUBSTR('POINT(-122.419956922531 37.7647100858191)', '\d.+') as geom_ from dual a);

关于如何从POINT(-122.419956922531 37.7647100858191) 中提取数字的任何提示?

【问题讨论】:

    标签: sql regex oracle substring


    【解决方案1】:

    这是一个简单的方法:

    WITH cteString
           AS (SELECT 'POINT(-122.419956922531 37.7647100858191)' AS POINT_STRING FROM DUAL)
    SELECT TO_NUMBER(REGEXP_SUBSTR(POINT_STRING, '[+-]?[0-9.]+', 1, 1)) AS LATITUDE,
           TO_NUMBER(REGEXP_SUBSTR(POINT_STRING, '[+-]?[0-9.]+', 1, 2)) AS LONGITUDE
      FROM cteString
    

    正则表达式 [+-]?[0-9.]+ 接受由一个或多个数字 0-9 和小数点组成的子字符串,可选地以符号字符开头。它查找第一个这样的子字符串,将生成的子字符串转换为 NUMBER,并将其作为名为 LATITUDE 的字段放入结果集中。然后它查找第二个这样的子字符串,将其转换为 NUMBER,并调用 LONGITUDE。

    db<>fiddle here

    【讨论】:

    • 它可能是一个更简单的正则表达式,但它会匹配无效的数字字符串(即....127.0.0.1)。
    • 测试驱动开发。 OP 提供了一组(公认最小的)测试数据。此代码正确处理给定的测试数据 - 因此,它满足给定的所有要求。如果 OP 关心提供上述代码工作的额外测试数据,那么可以进行更改 - 但在此之前,这工作得很好。 :-)
    【解决方案2】:
    SELECT REGEXP_SUBSTR(
             geom_,
             'POINT\(([+-]?\d+(\.\d+)?) ([+-]?\d+(\.\d+)?)\)',
             1,
             1,
             NULL,
             1
           ) AS longitude,
           REGEXP_SUBSTR(
             geom_,
             'POINT\(([+-]?\d+(\.\d+)?) ([+-]?\d+(\.\d+)?)\)',
             1,
             1,
             NULL,
             3
           ) AS latitude
    FROM   your_table;
    

    或:

    SELECT REGEXP_SUBSTR( geom_, '[+-]?\d+(\.\d+)?', 1, 1 ) AS longitude,
           REGEXP_SUBSTR( geom_, '[+-]?\d+(\.\d+)?', 1, 2 ) AS latitude
    FROM   your_table;
    

    或使用简单的字符串函数:

    SELECT SUBSTR( geom_, 7, INSTR( geom_, ' ' ) - 7 )
             AS longitude,
           SUBSTR( geom_, INSTR( geom_, ' ' ) + 1, LENGTH( geom_ ) - INSTR( geom_, ' ' ) - 1 )
             AS latitide
    FROM   your_table
    

    其中,对于样本数据:

    CREATE TABLE your_table ( geom_ ) AS
    SELECT 'POINT(-122.419956922531 37.7647100858191)' FROM DUAL;
    

    全部输出:

    经度 |纬度 :---------------- | :--------------- -122.419956922531 | 37.7647100858191

    (注意:如果您想要一个数字而不是包含数值的字符串,请将输出包装在 TO_NUMBER 中。)

    db小提琴here


    更新:

    如果您的小数分隔符通常为,,那么您可以使用TO_NUMBER,并在使用TO_NUMBER 时明确指定. 小数分隔符作为第三个参数:

    SELECT TO_NUMBER(
             REGEXP_SUBSTR( geom_, '[+-]?\d+(\.\d+)?', 1, 1 ),
             '999D9999999999999',
             'NLS_NUMERIC_CHARACTERS=''.,'''
           ) AS longitude,
           TO_NUMBER(
             REGEXP_SUBSTR( geom_, '[+-]?\d+(\.\d+)?', 1, 2 ),
             '999D9999999999999',
             'NLS_NUMERIC_CHARACTERS=''.,'''
           ) AS latitude
    FROM ( select 'POINT(-122.419956922531 37.7647100858191)' as geom_ from dual );
    

    db小提琴here

    【讨论】:

    • 感谢您的回答。我试过这个:select TO_NUMBER(REGEXP_SUBSTR( geom_, '[+-]?\d+(\.\d+)?', 1, 1 )) AS 经度,TO_NUMBER(REGEXP_SUBSTR( geom_, '[+-]?\d+ (\.\d+)?', 1, 2 )) AS 纬度来自 (select a.*, REGEXP_SUBSTR('POINT(-122.419956922531 37.7647100858191)', '\d.+') as geom_ from dual a) 但我得到错误:01722. 00000 - “无效号码” *原因:指定的号码无效。 *操作:指定一个有效的数字。
    • @Qualculus_90 不要在内部子查询中使用REGEXP_SUBSTRdb<>fiddle
    • 由于某种原因,它不适用于我的 Oracle 18c XE。使用与您的小提琴相同的代码,即: SELECT TO_NUMBER(REGEXP_SUBSTR( geom_, '[+-]?\d+(\.\d+)?', 1, 1 )) AS longitude, TO_NUMBER(REGEXP_SUBSTR( geom_, ' [+-]?\d+(\.\d+)?', 1, 2 )) 作为纬度 FROM(从 dual 中选择 'POINT(-122.419956922531 37.7647100858191)' 作为 geom_);错误:01722. 00000 - “无效号码” *原因:指定的号码无效。 *操作:指定一个有效的数字。
    • 好的,工作得很好。我不得不替换'。和 ','。谢谢
    • @Qualculus_90 添加了有关数字中的小数点分隔符是否显示为逗号 (,) 的更新。
    猜你喜欢
    • 1970-01-01
    • 2014-12-12
    • 2016-08-19
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    相关资源
    最近更新 更多