es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Oracle REGEXP_LIKE solución alternativa para lookahead y lookbehind

Estoy teniendo dificultades para construir una declaración regexp_like que funcione en Oracle. Necesito comparar una serie de filas, cada una de las cuales tiene un campo que contiene un conjunto de números separados por comas (siempre números). Necesito activar e inactivar cuentas diariamente en función de cómo cambian estos números.

Aquí hay varios ejemplos de los campos. (cada fila a continuación es el resultado en el campo)

9,18,31,32,50,725
17,20,31,32,50,725
17,18,20,22,50,725
9,18,31,49,50,500
49,22,9,25,222
18,18,31,9,50,725
49,31,9,25,292

Necesito encontrar cualquier fila que tenga uno o más de los siguientes números: 9, 20, 22, 50. (Otros lugares en el código pueden necesitar solo 9 o solo 20 y 22. Pero el principio se mantiene. Si el número es 500, no puede ser seleccionado. Debe ser 50).

La siguiente expresión regular funciona en Python, en mi búsqueda de Notepad++ y en un generador de expresiones regulares en línea:

((?<!\d)9|(?<!\d)20(?!\d)|(?<!\d)22(?!\d)|(?<!\d)50(?!\d))

Se basa en la anticipación negativa y el aftermino negativo. Pero debido a que Oracle no admite el uso de anticipación y aftermino, estoy confundido.

Aquí hay un fragmento de código de ejemplo que funciona si uso regexp sin anticipación y aftermino.

DECLARE
v_search_string varchar2(60);
BEGIN
v_search_string := ‘49,31,9,25,50,292’;

IF REGEXP_LIKE( v_search_string, ‘((?<!\d)9|(?<!\d)20(?!\d)|(?<!\d)22(?!\d)|(?<!\d)50(?!\d))’) THEN
dbms_output.put_line(‘Yes’);
ELSE
dbms_output.put_line(‘No’);
END IF;
END;

En este caso, debería obtener ‘Yes’ en mi dbms_output porque debería coincidir con ’50’.

¿Alguna idea?
PD: Estoy abierto a que alguien diga “oye, tonto, sería más fácil hacer ESTO”.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, dado que Oracle no admite mirar alrededor (lookarounds), no puedes utilizar la expresión regular que has proporcionado en Oracle. Sin embargo, hay una manera alternativa de lograr el resultado deseado.

    Un enfoque sería dividir el campo separado por comas en valores individuales y luego verificar cada valor en el conjunto de números que te interesa. Podrías utilizar la función REGEXP_SUBSTR para extraer cada valor y luego verificar si está en el conjunto deseado utilizando el operador IN. Aquí tienes un ejemplo:

    DECLARE 
        v_search_string    varchar2(60);
    BEGIN
        v_search_string := '49,31,9,25,50,292';
    
        IF (REGEXP_SUBSTR(v_search_string, '\d+', 1, level) IN ('9', '20', '22', '50'))
        LOOP
            dbms_output.put_line('Sí');
            EXIT;
        END LOOP;
    
        dbms_output.put_line('No');
    END;
    

    Este código recorrerá cada valor en el campo separado por comas y verificará si está en el conjunto de números de interés. Si encuentra una coincidencia, mostrará ‘Sí’ y saldrá del bucle. Si no hay coincidencias, mostrará ‘No’.

    Este enfoque no es tan elegante como usar mirar alrededor, pero funcionará en Oracle sin ellos.

Comments are closed.