查找varchar2()中的所有匹配项

时间:2013-03-15 14:01:53

标签: sql regex oracle

我的专栏varchar2包含以下数据:....[A1]...[A2]... 我想要取出[]封装的所有数据,这些数据以字母开头,可以有一个或两个数字,即:[B1][B23]

所以我想要类似:“WHERE列与'[__]' OR column is like '[___]'类似,但_不是任何值,而是字母或数字。

是否有可能将它们存储起来供以后使用?

2 个答案:

答案 0 :(得分:1)

您可以使用REGEXP_LIKE查找与正则表达式匹配的值:

[...] WHERE REGEXP(col_name, '\[[A-Z][0-9]{1,2}\]');

答案 1 :(得分:1)

好问题! Here's a Fiddle显示如何将匹配项查询到结果集中。

这里有一个很长的解释,以防小提琴中的查询没有意义:)

我正在使用名为RegEx_Test的表格,其中包含MyVal列。这是表格的内容:

MyVal
------------------------------
[A1][abc][B23][D123]a33[bx5]
[Z15][ax0][B0][F13]R3
[X215][A3A][J99]F33F33G24[43][R3]
[Z99][c1][F3][d33]3x24[Y3][f13]
[9a][D41][Q39][XX12]B27[T03][J12]

你的正则表达式是:\[[[:alpha:]][[:digit:]]{1,2}\]。除了POSIX :alpha::digit:指标外,它与其他答案相同,在国际字符集的情况下更安全。

首先,您需要知道任何一行的最大匹配数。请使用REGEXP_COUNT

SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
  FROM Regex_Test

MAX(REGEXP_COUNT(My...
----------------------
                     6

使用该最大计数来获取“计数器”表(这是下面的SELECT ... FROM DUAL)并使用查询交叉加入计数器表,该查询将使用REGEXP_SUBSTR提取您的值。 REGEXP_SUBSTR有一个“occurrence”参数,它将使用Counter

SELECT
  MyVal,
  Counter,
  REGEXP_SUBSTR(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]', 1, Counter) Matched
FROM Regex_Test
CROSS JOIN (
   SELECT LEVEL Counter
   FROM DUAL
   CONNECT BY LEVEL <= (
     SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
     FROM Regex_Test)) Counters

这是针对我的表运行的示例(部分结果):

MyVal                              Counter Matched
---------------------------------- ------- -------
[9a][D41][Q39][XX12]B27[T03][J12]        1 [D41]
[9a][D41][Q39][XX12]B27[T03][J12]        2 [Q39]
[9a][D41][Q39][XX12]B27[T03][J12]        3 [T03]
[9a][D41][Q39][XX12]B27[T03][J12]        4 [J12]
[9a][D41][Q39][XX12]B27[T03][J12]        5
[9a][D41][Q39][XX12]B27[T03][J12]        6
[A1][abc][B23][D123]a33[bx5]             1 [A1]
[A1][abc][B23][D123]a33[bx5]             2 [B23]
[A1][abc][B23][D123]a33[bx5]             3
... and so on - total is 30 rows

此时,您有一个单独匹配的结果集,以及一行中小于最大匹配项的空值。比赛仍然有他们的周围括号。使用外部查询来覆盖整个事物,该查询将过滤掉空值并删除括号,并且您有最终列表:

SELECT SUBSTR(Matched, 2, LENGTH(Matched)-2) FROM (
  SELECT
    MyVal,
    Counter,
    REGEXP_SUBSTR(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]', 1, Counter) Matched
  FROM Regex_Test
  CROSS JOIN (
     SELECT LEVEL Counter
     FROM DUAL
     CONNECT BY LEVEL <= (
       SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
       FROM Regex_Test)) Counters
) WHERE Matched IS NOT NULL

这是小提琴上的查询,可以在另一个查询中使用。