Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Finden Sie alle Übereinstimmungen in einem varchar2 ()

Tolle Frage! Hier ist eine Geige zeigt, wie die Übereinstimmungen in eine Ergebnismenge abgefragt werden.

Und hier ist die lange Erklärung, falls die Abfrage in der Fiddle keinen Sinn ergibt :)

Ich verwende eine Tabelle namens RegEx_Test mit einer Spalte MyVal . Hier ist der Inhalt der Tabelle:

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]

Ihr regulärer Ausdruck lautet durchgehend:\[[[:alpha:]][[:digit:]]{1,2}\] . Es ist dasselbe wie in der anderen Antwort, außer mit dem POSIX :alpha: und :digit: Indikatoren, die bei internationalen Zeichensätzen sicherer sind.

Zuerst müssen Sie die maximale Anzahl von Übereinstimmungen in jeder Zeile kennen. Verwenden Sie REGEXP_COUNT dazu:

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

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

Verwenden Sie diese maximale Anzahl, um eine "Zähler"-Tabelle zu erhalten (das ist die SELECT ... FROM DUAL unten) und verknüpfen Sie die Zählertabelle mit einer Abfrage, die Ihre Werte mit REGEXP_SUBSTR abruft . REGEXP_SUBSTR hat einen "Occurrence"-Parameter und verwendet den 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

Hier ist ein Beispiellauf gegen meine Tabelle (Teilergebnisse):

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

An diesem Punkt haben Sie eine Ergebnismenge einzelner Übereinstimmungen plus Nullen, wenn eine Zeile weniger als die maximale Übereinstimmung hatte. Die Streichhölzer haben immer noch ihre umgebenden Klammern. Umgeben Sie das Ganze mit einer äußeren Abfrage, die die Nullen herausfiltert und die Klammern entfernt, und Sie haben Ihre endgültige Liste:

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

Dies ist die Abfrage, die sich auf der Fiddle befindet, und sie kann in einer anderen Abfrage verwendet werden.