1

我正在尝试使用 Oracle 的REGEXP_SUBSTR()函数从文本字段中提取分钟数。

数据:

Treatment of PC7, PT1 on left. 15 min.
15 minutes.
15 minutes
15 mins.
15 mins
15 min.
15 min
15min
15

在每种情况下,我都希望提取字符串的“15”部分。

尝试:

  • \d+获取所有数值,包括“7”和“1”,这是不可取的。
  • (\d)+(?=\ ?min)从除最后一行之外的所有行中获取“15”。
  • (?((\d)+(?=\ ?min))((\d)+(?=\ ?min))|\d+),一个条件语句,不匹配任何东西。

我的条件语句有什么问题?

** 编辑 **

WITH DATA AS (

  SELECT 'Treatment of PC7, PT1 on left. 15 min.' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15 minutes.' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15 minutes' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15 mins.' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15 mins' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15 min.' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15 min' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15min' COMMENTS FROM DUAL

  UNION ALL

  SELECT '15' COMMENTS FROM DUAL

)

SELECT  COMMENTS,
        REGEXP_SUBSTR(COMMENTS, '(\d+)\s?(?:min.*)?$', 1, 1) A,
        REGEXP_SUBSTR(COMMENTS, '\d+?(?= ?min)|^\d+$', 1, 1) B,
        REGEXP_SUBSTR(COMMENTS, '\d+?(?: ?min)|^\d+$', 1, 1) C

FROM DATA

结果(必须有比“代码示例”更好的方式来格式化列):

COMMENTS A B C
Treatment of PC7, PT1 on left. 15 min.          
15 minutes.         
15 minutes          
15 mins.            
15 mins         
15 min.         
15 min          
15min           
15  15  15  15
4

3 回答 3

3

此正则表达式将为您工作。

^.*?(\d+)(( ?min.*$)|$)

解释

  • ^.*?- 匹配字符串的开头,后跟任意字符 0 次或更多次
  • (\d+)- 匹配至少一位数字并将其存储在反向引用位置 1
  • ( ?min.*$)- 匹配空格(可能)、min、任何字符(可能),然后是字符串的结尾。
  • (...|$)- 如果找不到min,它将查看是否有字符串的结尾。

然后,不要使用REGEXP_SUBSTR(),而是REGEXP_REPLACE()像这样使用,将整个字符串替换为存储在反向引用位置 1 (您的号码)中的内容:

REGEXP_REPLACE(COMMENTS, '^.*?(\d+)(( ?min.*$)|$)', '\1') A
于 2012-11-06T17:08:33.090 回答
1

如果您可以保证时间戳将始终显示为字符串的最后一部分,则可以:

(\d+)\s?(?:min.*)?$

我不知道 Oracle 是否支持非捕获组,但这很容易解决。我的经验是它的 RegExp 引擎仅限于非常普通的东西。

于 2012-11-06T17:12:32.830 回答
0

使用多个表达式的替代工作解决方案:

TO_NUMBER(
    CASE
        -- number only
        WHEN LENGTH( REGEXP_SUBSTR(MEAS_COMMENT, '^\d+$', 1, 1) ) >0 THEN REGEXP_SUBSTR(MEAS_COMMENT, '^\d+$', 1, 1)
        -- XX min
        WHEN LENGTH( REGEXP_SUBSTR(MEAS_COMMENT, '\d+( ?min)', 1, 1) ) >0 THEN REGEXP_SUBSTR(REGEXP_SUBSTR(MEAS_COMMENT, '\d+( ?min)', 1, 1), '\d+', 1, 1)
    END
) MINUTES

** 编辑 **

-- same results without the `CASE` statement:
TO_NUMBER( REGEXP_SUBSTR(REGEXP_SUBSTR(COMMENTS, '(\d+)( ?min|$)', 1, 1), '\d+', 1, 1) )
于 2012-11-06T18:57:08.077 回答