查找具有精确长度3的Oracle regexp的数字

时间:2013-11-23 14:48:00

标签: sql regex oracle

我想只得到456。

我尝试了这个正则表达式,但是我得到了包含3位数字符号的所有数字,456,46354376等。

select regexp_substr(MY_COLUMN,'([[:digit:]]{3})') from MY_TABLE

3 个答案:

答案 0 :(得分:5)

我不太清楚你是否想要完全匹配或子串匹配,所以我已经包含了各种选项:

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE MY_TABLE (MY_COLUMN) AS
          SELECT '456' FROM DUAL
UNION ALL SELECT '12345678' FROM DUAL
UNION ALL SELECT 'abc 123 def 456' FROM DUAL;

查询1

如果您只想要MY_COLUMN包含3位数字的行,那么您可以使用包含在起始字符串(^)和结束字符串({{1)中的正则表达式}})锚点:

$

<强> Results

    SELECT MY_COLUMN
    FROM   MY_TABLE
    WHERE  REGEXP_LIKE( MY_COLUMN, '^[[:digit:]]{3}$' )

查询2

或者,如果您使用的是Oracle 11g,那么您可以使用较不详细的PERL语法:

| MY_COLUMN |
|-----------|
|       456 |

<强> Results

    SELECT MY_COLUMN
    FROM   MY_TABLE
    WHERE  REGEXP_LIKE( MY_COLUMN, '^\d{3}$' )

查询3

如果要从列中提取第一个3位数字(可以包含周围文本或更多数字),则:

| MY_COLUMN |
|-----------|
|       456 |

<强> Results

    SELECT MY_COLUMN,
           REGEXP_INSTR( MY_COLUMN, '\d{3}' ), 
           REGEXP_SUBSTR( MY_COLUMN, '\d{3}' )
    FROM   MY_TABLE
    WHERE  REGEXP_LIKE( MY_COLUMN, '\d{3}' )

查询4

如果要从列中提取第一个完全正确的3位数字,请执行以下操作:

|       MY_COLUMN | REGEXP_INSTR(MY_COLUMN,'\D{3}') | REGEXP_SUBSTR(MY_COLUMN,'\D{3}') |
|-----------------|---------------------------------|----------------------------------|
|             456 |                               1 |                              456 |
|        12345678 |                               1 |                              123 |
| abc 123 def 456 |                               5 |                              123 |

<强> Results

    SELECT MY_COLUMN,
           REGEXP_SUBSTR( REGEXP_SUBSTR( MY_COLUMN, '(^|\D)\d{3}(\D|$)' ), '\d{3}' ) AS match
    FROM   MY_TABLE
    WHERE  REGEXP_LIKE( MY_COLUMN, '(^|\D)\d{3}(\D|$)' )

查询5

如果要从列中提取所有非重叠的3位数字(它可以包含周围文本),则:

|       MY_COLUMN | MATCH |
|-----------------|-------|
|             456 |   456 |
| abc 123 def 456 |   123 |

<强> Results

    WITH re_counts AS (
      SELECT MY_COLUMN,
             REGEXP_COUNT( MY_COLUMN, '\d{3}' ) AS re_count
      FROM   MY_TABLE
    )
    ,indexes AS (
      SELECT LEVEL AS "index"
      FROM   DUAL
      CONNECT BY LEVEL <= (SELECT MAX( re_count)  FROM re_counts)
    )
    SELECT MY_COLUMN,
           "index", 
           REGEXP_SUBSTR( MY_COLUMN, '\d{3}', 1, "index" )
    FROM   re_counts
           INNER JOIN
           indexes
           ON ("index" <= re_count)
    ORDER BY MY_COLUMN, "index"

查询6

如果您想提取所有正好是3位数的子匹配,那么:

|       MY_COLUMN | INDEX | REGEXP_SUBSTR(MY_COLUMN,'\D{3}',1,"INDEX") |
|-----------------|-------|--------------------------------------------|
|        12345678 |     1 |                                        123 |
|        12345678 |     2 |                                        456 |
|             456 |     1 |                                        456 |
| abc 123 def 456 |     1 |                                        123 |
| abc 123 def 456 |     2 |                                        456 |

<强> Results

    WITH re_counts AS (
      SELECT MY_COLUMN,
             REGEXP_COUNT( MY_COLUMN, '(^|\D)\d{3}(\D|$)' ) AS re_count
      FROM   MY_TABLE
    )
    ,indexes AS (
      SELECT LEVEL AS "index"
      FROM   DUAL
      CONNECT BY LEVEL <= (SELECT MAX( re_count)  FROM re_counts)
    )
    SELECT MY_COLUMN,
           "index", 
           REGEXP_SUBSTR( REGEXP_SUBSTR( MY_COLUMN, '(^|\D)\d{3}(\D|$)', 1, "index" ), '\d{3}' ) AS match
    FROM   re_counts
           INNER JOIN
           indexes
           ON ("index" <= re_count)
    ORDER BY MY_COLUMN, "index"

查询7

如果您想从列中提取所有3位数字,无论这些匹配是否部分重叠,那么:

|       MY_COLUMN | INDEX | MATCH |
|-----------------|-------|-------|
|             456 |     1 |   456 |
| abc 123 def 456 |     1 |   123 |
| abc 123 def 456 |     2 |   456 |

<强> Results

    WITH positions AS (
      SELECT LEVEL AS pos
      FROM   DUAL
      CONNECT BY LEVEL <= (SELECT MAX( LENGTH( MY_COLUMN ) - 2 )  FROM MY_TABLE )
    )
    SELECT MY_COLUMN,
           pos, 
           SUBSTR( MY_COLUMN, pos, 3 )
    FROM   MY_TABLE
           INNER JOIN
           positions
           ON (pos <= LENGTH( MY_COLUMN ) - 2 )
    WHERE  REGEXP_LIKE( SUBSTR( MY_COLUMN, pos, 3 ), '^\d{3}$' )
    ORDER BY MY_COLUMN, pos

答案 1 :(得分:1)

您已对该号码进行子串...如果您正在搜索正好为3位数的号码,请使用LENGTH()

 select * from my_table where length(my_column) = 3

这预先假定您已将数字存储在NUMBER列中。如果那里可能还有字符,请使用REGEXP_LIKE()并确保将正则表达式绑定到字符串的开头(使用^运算符)和结尾($

select * from my_table where regexp_like( my_column, '^[[:digit:]]{3}$')

您不会检查您的号码是否位于字符串的开头和结尾,因此您可以通过3个号码获取所有内容。

答案 2 :(得分:0)

您可以使用此模式:

(^|[^[:digit:]])([[:digit:]]{3})($|[^[:digit:]])

其中[^[:digit:]] 所有不是数字^$是字符串锚点的开头和结尾。