2016-12-16 1 views
0

Wie Sie wissen, Oracle POSIX Implementierung von Regexes unterstützt keine Wortgrenzen. Eine Abhilfe ist hier vorgeschlagen: Oracle REGEXP_LIKE and word boundariesOracle regexp_like Wortgrenzen mehrere Wörter Abhilfe

Allerdings funktioniert es nicht, wenn ich möchte, zum Beispiel alle 4 Zeichenfolgen auswählen. Betrachten Sie dies zum Beispiel:

myvar:=regexp_substr('test test','(^|\s|\W)[\S]{4}($|\s|\W)') 

Dies wählt offensichtlich nur das erste Auftreten. Ich weiß nicht, wie man das in der Oracle-Welt macht, obwohl es normalerweise einfach (\b)[\S]{4}(\b) ist. Das Problem ist, dass die meisten woraround auf einige nicht vorhandene Funktion verlassen, wie Lookarounds usw.

Antwort

0
select xmlcast(xmlquery('for $token in ora:tokenize(concat(" ",$in)," ") 
       where string-length($token) = $size 
       return $token' passing 'test test' as "in", 4 as "size" returning content) as varchar2(2000)) word from dual; 

Xquery und FLWOR expresion.

concat(" ",$in) - Problemumgehung, wenn die Eingabezeichenfolge null ist oder nur 1 Matchingwort vorhanden ist.

ora:tokenize - tokenize Zeichenfolge von "Raum"

string-length($token) = $size überprüfen, ob Token entsprechende Länge hat.

xmlcast - konvertieren xmltype

Leicht zu varchar2? Jede Frage :)

+0

Ich habe so viele wunderbare Lösungen mit Oracle XML gesehen, aber ich bin total ignorant darüber. Kann jemand ein Buch oder eine Website empfehlen, um mich zu starten? –

0
DECLARE 
    str  VARCHAR2(200) := 'test test'; 
    pattern VARCHAR2(200) := '(\w+)($|\s+|\W+)'; 
    match VARCHAR2(200); 
BEGIN 
    FOR i IN 1 .. REGEXP_COUNT(str, pattern) LOOP 
    match := REGEXP_SUBSTR(str, pattern, 1, i, NULL, 1); 
    IF LENGTH(match) = 4 THEN 
     DBMS_OUTPUT.PUT_LINE(match); 
    END IF; 
    END LOOP; 
END; 
/

oder (ohne REGEXP_COUNT oder den 6. Parameter von REGEXP_SUBSTR, die in 11G eingeführt wurde):

DECLARE 
    str    VARCHAR2(200) := 'test test'; 
    pattern CONSTANT VARCHAR2(3) := '\w+'; 
    match   VARCHAR2(200); 
    i    NUMBER(4,0) := 1; 
BEGIN 
    match := REGEXP_SUBSTR(str, pattern, 1, i); 
    WHILE match IS NOT NULL LOOP 
    IF LENGTH(match) = 4 THEN 
     DBMS_OUTPUT.PUT_LINE(match); 
    END IF; 
    i  := i + 1; 
    match := REGEXP_SUBSTR(str, pattern, 1, i); 
    END LOOP; 
END; 
/

Ausgang:

test 
test 

Wenn Sie möchten, Um dies in SQL zu verwenden, können Sie es einfach in eine Pipeline-Funktion oder eine Funktion, die eine Sammlung zurückgibt, übersetzen.

+0

Vielen Dank. Leider bin ich auf 10g und REGEXP_COUNT ist nicht verfügbar. Ich denke, sie haben es in 11g eingeführt. – Dimiter

+0

@Dimiter Hinzugefügt (hoffentlich) Oracle 10g Lösung. – MT0

+0

@MTO: Vielen Dank! Sehr geschätzt! – Dimiter