2011-09-27 8 views
23

Sto riscontrando un problema con i limiti di lavoro corrispondenti con REGEXP_LIKE. La seguente query restituisce una singola riga, come previsto.Oracle REGEXP_LIKE e limiti di parole

select 1 from dual 
where regexp_like('DOES TEST WORK HERE','TEST'); 

Ma voglio uguagliare anche sui confini delle parole. Quindi, aggiungendo i caratteri "\ b" viene fornita questa query

select 1 from dual 
where regexp_like('DOES TEST WORK HERE','\bTEST\b'); 

In esecuzione restituisce zero righe. Qualche idea?

+0

Che strano. Non riesco a farlo funzionare, ad esempio, 'selezionare regexp_replace ('DOES TEST WORK HERE', '\ bTEST \ b', 'X') da dual;' restituisce 'DOES TEST WORK HERE'. .. Funziona se si usa '\ W', ma non è lo stesso di' \ b': P – Xophmeister

risposta

35

credo si vuole provare

select 1 from dual 
    where regexp_like ('does test work here', '(^|\s)test(\s|$)'); 

perché il \b non appare in questa lista: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_regexp.htm#i1007670

Il \s fa in modo che si avvia test e termina in uno spazio bianco. Questo non è sufficiente, tuttavia, poiché la stringa test potrebbe anche apparire all'inizio o alla fine della stringa che corrisponde. Pertanto, utilizzo l'alternativa (indicata dallo |) ^ per l'inizio della stringa e $ per la fine della stringa.

Update (dopo 3 anni +) ... Si dà il caso, avevo bisogno di questa funzionalità oggi, e mi sembra che anche meglio un'espressione regolare è (^|\s|\W)test($|\s|\W) (The missing \b regular expression special character in Oracle).

+0

Grazie per quello. Ho trovato molte risorse in rete (ad es. Http://psoug.org/snippet/Regular-Expressions--Regexp-Cheat-Sheet_856.htm) che mi hanno suggerito di farlo. In realtà voglio corrispondere all'inizio o alla fine di una stringa, o un carattere "non parole" nel mio caso - quindi ho cambiato \ W al posto di \ s. –

+0

Sì, sembra che Oracle abbia scelto di non supportare '\ b' sebbene si tratti di un token di espressioni regolari piuttosto standard. –

+0

Le espressioni regolari di Oracle utilizzano lo standard POSIX ERE (con alcuni miglioramenti come i riferimenti incrociati) che non supporta i limiti delle parole. –

0

In generale, vorrei attenermi alla soluzione di René, con l'eccezione quando è necessario che la corrispondenza sia di lunghezza zero. cioè non vuoi effettivamente catturare il carattere non parola all'inizio/fine.

Ad esempio, se la nostra stringa è test test allora (\b)test(\b) corrisponderà due volte ma (^|\s|\W)test($|\s|\W) corrisponderà solo alla prima occorrenza. Almeno, questo è certamente il caso se si tenta di utilizzare regexp_substr.

Esempio

SELECT regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 1, 'i'), regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 2, 'i') FROM dual;

Returns

test |NULL