CHR(0)
jest znakiem używanym do zakończenia łańcucha w języku programowania C (między innymi).
Kiedy zdasz CHR(0)
do funkcji, z kolei przekaże go do funkcji niższego poziomu, która przeanalizuje przekazane ciągi i zbuduje z nich wzorzec wyrażenia regularnego. Ten wzorzec wyrażenia regularnego zobaczy CHR(0)
i pomyśl, że jest to terminator ciągu i zignoruj resztę wzorca.
Zachowanie jest łatwiejsze do zauważenia dzięki REGEXP_REPLACE
:
SELECT REGEXP_REPLACE( 'abc' || CHR(0) || 'e', CHR(0), 'd' )
FROM DUAL;
Co się stanie, gdy uruchomisz to:
CHR(0)
jest kompilowany do wyrażenia regularnego i staje się terminatorem ciągu.- Teraz wzorzec jest tylko terminatorem ciągu, więc wzorzec jest ciągiem o zerowej długości.
- Wyrażenie regularne jest następnie dopasowywane do ciągu wejściowego i odczytuje pierwszy znak
a
i stwierdza, że łańcuch o zerowej długości może być dopasowany przeda
więc zastępuje nic, co pasowało przeda
zd
dając wynikda
. - Następnie powtórzy się dla następnego znaku przekształcającego
b
dodb
. - i tak dalej, aż dojdziesz do końca ciągu, kiedy będzie pasował do wzorca o zerowej długości i dołączy końcowy
d
.
A otrzymasz wynik:
dadbdcd_ded
(gdzie _ to CHR(0)
znak. )
Uwaga:CHR(0)
w wejściu nie jest zastępowany.
Jeśli program klienta, którego używasz, również obcina ciąg w CHR(0)
możesz nie widzieć całych danych wyjściowych (jest to problem z tym, jak twój klient reprezentuje ciąg, a nie z danymi wyjściowymi Oracle), ale można to również wyświetlić za pomocą DUMP()
:
SELECT DUMP( REGEXP_REPLACE( 'abc' || CHR(0) || 'e', CHR(0), 'd' ) )
FROM DUAL;
Wyjścia:
Typ=1 Len=11: 100,97,100,98,100,99,100,0,100,101,100
[TL;DR] Więc co się dzieje z
REGEXP_LIKE( '1234567890', CHR(0) )
Utworzy wzorzec wyrażenia regularnego w postaci łańcucha o zerowej długości i będzie szukał dopasowania o zerowej długości przed 1
znak - który znajdzie, a następnie zwróci, że znalazł dopasowanie.