2011-10-13 14 views
37

Recibí esta consulta y deseo extraer el valor entre los corchetes.¿Cómo extraer el grupo de la expresión regular en Oracle?

select de_desc, regexp_substr(de_desc, '\[(.+)\]', 1) 
from DATABASE 
where col_name like '[%]'; 

Sin embargo, me da el valor con los corchetes como "[PRUEBA]". Solo quiero "TEST". ¿Cómo modifico la consulta para obtenerla?

Respuesta

67

El tercer parámetro de la función REGEXP_SUBSTR indica la posición en la cadena de destino (de_desc en su ejemplo) donde desea iniciar la búsqueda. Suponiendo que se encuentra una coincidencia en la porción dada de la cadena, no afecta lo que se devuelve.

En Oracle 11g, hay un sexto parámetro para la función, que creo que es lo que está intentando usar, que indica el grupo de captura que desea devolver. Un ejemplo de uso adecuado sería:

SELECT regexp_substr('abc[def]ghi', '\[(.+)\]', 1,1,NULL,1) from dual; 

Cuando el último parámetro 1 indican el número del grupo de captura que desea devolver.

10g no parecen tener esta opción, pero en su caso se puede lograr el mismo resultado con:

select substr(match, 2, length(match)-2) from (
SELECT regexp_substr('abc[def]ghi', '\[(.+)\]') match FROM dual 
); 

ya que saber que un partido tendrá exactamente un exceso de caracteres al comienzo y al final. (Alternativamente, puede usar RTRIM y LTRIM para eliminar corchetes de ambos extremos del resultado.)

+0

Lo sorprendente es que el sexto parámetro no se menciona en la documentación REGEXP_SUBSTR oficial de Oracle. Gracias por señalar que existe. –

14

Debe reemplazar y usar un patrón de expresiones regulares que coincida con toda la cadena.

select regexp_replace(de_desc, '.*\[(.+)\].*', '\1') from DATABASE; 
+0

En mi humilde opinión, este es el modo más simple, fácil de recordar, más flexible y, por lo tanto, la mejor manera de hacerlo. –

+7

Advertiría a cualquiera que use 'REGEXP_REPLACE' para obtener el grupo de captura que, si el patrón no coincide, Oracle devolverá el valor completo, mientras que el comportamiento que probablemente desee es que devuelva' null'. Por ejemplo, 'REGEXP_REPLACE ('abcdefghi', '. * \ [(. +) \]. *', '\ 1')' (el patrón no coincide) devuelve 'abcdefghi'. Esto me hizo tropezar una vez. – Jared

+0

El problema aquí es que Oracle regexp no proporciona una función para devolver la parte de la cadena que coincide con un grupo de captura. Puede intentar usar una consulta recursiva (seleccione ... desde la pestaña conectarse por ...) pero desconfíe del posible problema de rendimiento. – Cyryl1972

Cuestiones relacionadas