2011-09-27 25 views
23

Tengo un problema con la coincidencia de límites de trabajo con REGEXP_LIKE. La siguiente consulta devuelve una sola fila, como se esperaba.Oracle REGEXP_LIKE y límites de palabras

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

Pero quiero hacer coincidir los límites de las palabras también. Entonces, agregando los caracteres "\ b" da esta consulta

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

Ejecutando esto devuelve cero filas. ¿Algunas ideas?

+0

eso es raro. No puedo hacer que funcione, tampoco ... Por ejemplo, 'select regexp_replace ('DOES TEST WORK HERE', '\ bTEST \ b', 'X') de dual;' returns 'DOES TEST WORK AQUÍ'. .. Funciona si usas '\ W', pero eso no es lo mismo que' \ b': P – Xophmeister

Respuesta

35

Creo que usted quiere probar

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

porque el \b no aparece en esta lista: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_regexp.htm#i1007670

El \s se asegura de que el examen comience y termine en el espacio en blanco. Sin embargo, esto no es suficiente, ya que la cadena test también podría aparecer al principio o al final de la cadena que se está emparejando. Por lo tanto, utilizo la alternativa (indicada por |) ^ para el inicio de la cadena y $ para el final de la cadena.

Update (después de 3 años +) ... Si llega el caso, necesitaba esta funcionalidad hoy, y me parece que aún mejor una expresión regular es (^|\s|\W)test($|\s|\W) (The missing \b regular expression special character in Oracle).

+0

Gracias por eso. Encontré muchos recursos en la red (por ejemplo, http://psoug.org/snippet/Regular-Expressions--Regexp-Cheat-Sheet_856.htm) que sugerían que podía. De hecho, quiero unir el principio o el final de una cadena, o un carácter "sin palabra" en mi caso, así que cambié \ W en lugar de \ s. –

+0

Sí, parece que Oracle eligió no admitir '\ b' aunque este es un token de expresión regular bastante estándar. –

+0

Las expresiones regulares de Oracle usan el estándar POSIX ERE (con algunas mejoras, como las referencias retrospectivas) que no admite límites de palabras. –

0

En general, me quedaré con la solución de René, con la excepción de cuando necesitas que la coincidencia sea de longitud cero. es decir, no desea capturar realmente el carácter no verbal al principio/final.

Por ejemplo, si nuestra cadena es test test entonces (\b)test(\b) coincidirá dos veces pero (^|\s|\W)test($|\s|\W) solo coincidirá con la primera aparición. Al menos, ese es ciertamente el caso si intentas usar regexp_substr.

Ejemplo

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;

devoluciones

test |NULL

Cuestiones relacionadas