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

CHR(0) in REGEXP_LIKE

CHR(0) ist das Zeichen, das verwendet wird, um eine Zeichenkette in der Programmiersprache C (unter anderem) zu beenden.

Wenn Sie CHR(0) übergeben an die Funktion, die es wiederum an eine Funktion auf niedrigerer Ebene weitergibt, die die übergebenen Zeichenfolgen analysiert und aus dieser Zeichenfolge ein reguläres Ausdrucksmuster erstellt. Dieses reguläre Ausdrucksmuster sieht CHR(0) und denke, es ist das String-Endzeichen und ignoriere den Rest des Musters.

Das Verhalten ist mit REGEXP_REPLACE einfacher zu sehen :

SELECT REGEXP_REPLACE( 'abc' || CHR(0) || 'e', CHR(0), 'd' )
FROM   DUAL;

Was passiert, wenn Sie Folgendes ausführen:

  • CHR(0) wird in einen regulären Ausdruck kompiliert und wird zu einem String-Terminator.
  • Jetzt ist das Muster nur noch das String-Endzeichen und somit ist das Muster ein String der Länge Null.
  • Der reguläre Ausdruck wird dann mit der Eingabezeichenfolge abgeglichen und liest das erste Zeichen a und findet, dass eine Zeichenfolge der Länge Null vor dem a abgeglichen werden kann es ersetzt also das Nichts, auf das es vor dem a gematcht hat mit einem d was die Ausgabe da ergibt .
  • Es wird dann für das nächste Zeichen wiederholt, das b umwandelt zu db .
  • und so weiter, bis Sie das Ende der Zeichenfolge erreichen, wenn es mit dem Muster der Länge Null übereinstimmt, und hängen Sie ein abschließendes d an .

Und Sie erhalten die Ausgabe:

dadbdcd_ded

(wobei _ der CHR(0) ist Charakter. )

Hinweis:der CHR(0) in der Eingabe wird nicht ersetzt.

Wenn das von Ihnen verwendete Client-Programm auch die Zeichenfolge bei CHR(0) abschneidet Möglicherweise sehen Sie nicht die gesamte Ausgabe (dies ist ein Problem damit, wie Ihr Client die Zeichenfolge darstellt, und nicht mit der Ausgabe von Oracle), aber sie kann auch mit DUMP() angezeigt werden :

SELECT DUMP( REGEXP_REPLACE( 'abc' || CHR(0) || 'e', CHR(0), 'd' ) )
FROM DUAL;

Ausgaben:

Typ=1 Len=11: 100,97,100,98,100,99,100,0,100,101,100

[TL;DR] Was passiert also mit

REGEXP_LIKE( '1234567890', CHR(0) )

Es erstellt ein reguläres Ausdrucksmuster der Länge Null und sucht nach einer Übereinstimmung der Länge Null vor 1 Zeichen - das es findet und dann zurückgibt, dass es eine Übereinstimmung gefunden hat.