ABAP REPLACE: Reemplazar Cadenas de Caracteres - Con y Sin Expresiones Regulares

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

La sentencia REPLACE en ABAP se utiliza para encontrar ocurrencias de un patron de busqueda (ya sea una cadena de caracteres fija/subcadena o un patron definido por una Expresion Regular) dentro de un objeto de datos de tipo caracter (por ejemplo, STRING, C, N, D, T) y reemplazarlas por otra cadena de caracteres.

Un aspecto importante es que REPLACE modifica directamente la variable en la que se realiza el reemplazo (cambio “in place”).

Sintaxis

REPLACE [{FIRST OCCURRENCE}|{ALL OCCURRENCES OF}] " Que reemplazar? (Primero o Todos)
{<subcadena>}|{REGEX <regex>} " Que buscar? (Texto o Regex)
IN <variable> " Donde buscar/reemplazar? (Se modifica!)
WITH <reemplazo> " Con que reemplazar?
[<opciones>]. " Opciones adicionales
  • FIRST OCCURRENCE: Reemplaza solo la primera ocurrencia encontrada del patron de busqueda.
  • ALL OCCURRENCES OF (Predeterminado, si falta FIRST OCCURRENCE): Reemplaza todas las ocurrencias no superpuestas del patron de busqueda.
  • <subcadena>: El texto exacto (literal o variable) que se buscara.
  • REGEX <regex>: Una Expresion Regular (literal o variable, sintaxis PCRE) que describe el patron a buscar. Esto permite busqueda flexible de patrones.
  • IN <variable>: La variable de tipo caracter cuyo contenido se buscara y modificara. Atencion: El contenido de esta variable se modifica directamente!
  • WITH <reemplazo>: La cadena de caracteres (literal o variable) que se insertara en lugar de los patrones de busqueda encontrados.
  • <opciones>: (Seleccion)
    • IGNORING CASE / RESPECTING CASE (Predeterminado): Controla si se respeta mayusculas/minusculas en la busqueda.
    • REPLACEMENT COUNT <cnt>: Almacena la cantidad de reemplazos realizados en la variable <cnt> (Tipo I).
    • REPLACEMENT OFFSET <off>: Almacena el offset de la posicion despues del ultimo reemplazo en <off>.
    • REPLACEMENT LENGTH <len>: Almacena la longitud del ultimo string de reemplazo insertado en <len>.
    • RESULTS <results>: Permite almacenar informacion detallada sobre cada reemplazo (posicion, longitud, etc.) en una estructura o tabla interna (similar a FIND).
    • IN SECTION OFFSET <sec_off> LENGTH <sec_len> OF: Limita la busqueda y reemplazo a una subseccion de la <variable>.

Caracteres Especiales en el Reemplazo (<reemplazo>) con REGEX

Cuando se usa REGEX, se pueden utilizar marcadores de posicion especiales en el string de <reemplazo>:

  • $0 o $&: Representa la seccion de texto completa encontrada por el Regex.
  • $1, $2, $3…: Representa el texto capturado por el primer, segundo, tercer… grupo entre parentesis (Capture Group) en la Expresion Regular.
  • ` (Backtick): Representa la parte de la <variable> antes de la seccion de texto encontrada.
  • $': Representa la parte de la <variable> despues de la seccion de texto encontrada.
  • $$: Representa un signo de dolar literal ($) en el texto de reemplazo.

Comportamiento con Longitud Fija (Tipo C)

Cuando <variable> es de tipo C (longitud fija):

  • Si el <reemplazo> es mas corto que el texto encontrado, el resto del espacio original se rellena con espacios a la derecha.
  • Si el <reemplazo> es mas largo que el texto encontrado y el resultado excederia la longitud definida de la variable, el resultado se trunca a la derecha. Es posible la perdida de datos!
  • Recomendacion: Para reemplazos donde la longitud puede cambiar significativamente, es mas seguro usar una variable de destino de tipo STRING.

Campos del Sistema

  • sy-subrc:
    • 0: Se realizo al menos un reemplazo.
    • 4: No se encontro el patron de busqueda, no se realizo ningun reemplazo.
  • sy-fdpos: Contiene el offset de la posicion despues del ultimo texto reemplazado o insertado.

Alternativas Modernas

Especialmente para variables STRING, el ABAP moderno ofrece alternativas que a veces son mas legibles o no modifican la variable original:

  • Funcion replace(...): Devuelve un nuevo String en el que se han realizado los reemplazos.
    DATA(new_string) = replace( val = old_string sub = 'viejo' with = 'nuevo' occ = 0 ). " occ=0 -> todos
  • String-Templates (|...|): Se pueden usar para reconstrucciones mas complejas de strings.

Sin embargo, REPLACE sigue siendo una herramienta poderosa, especialmente por la opcion REGEX.

Ejemplos

1. Reemplazar Primera Ocurrencia

DATA text1 TYPE string VALUE 'Test: Manzana, Pera, Manzana'.
REPLACE FIRST OCCURRENCE OF 'Manzana' IN text1 WITH 'Naranja'.
WRITE: / text1. " Salida: Test: Naranja, Pera, Manzana

2. Reemplazar Todas las Ocurrencias (Case-Insensitivo)

DATA text2 TYPE string VALUE 'Fallo: ERROR Codigo 1, Error Codigo 2'.
REPLACE ALL OCCURRENCES OF 'error' IN text2 WITH 'ADVERTENCIA' IGNORING CASE.
WRITE: / text2. " Salida: Fallo: ADVERTENCIA Codigo 1, ADVERTENCIA Codigo 2

3. Contar Cantidad de Reemplazos

DATA text3 TYPE string VALUE 'a b c a b c a'.
DATA count TYPE i.
REPLACE ALL OCCURRENCES OF 'a' IN text3 WITH 'X' REPLACEMENT COUNT count.
WRITE: / text3. " Salida: X b c X b c X
WRITE: / 'Cantidad de reemplazos:', count. " Salida: 3

4. Reemplazar con Expresion Regular (Multiples Espacios -> 1 Espacio)

DATA text4 TYPE string VALUE 'Palabra1 Palabra2 Palabra3 Palabra4'.
REPLACE ALL OCCURRENCES OF REGEX `\s{2,}` IN text4 WITH ` `. " \s{2,} = 2 o mas espacios
WRITE: / text4. " Salida: Palabra1 Palabra2 Palabra3 Palabra4

5. Regex con Capture Groups (Reformatear Fecha YYYYMMDD -> DD.MM.YYYY)

DATA date_in TYPE string VALUE '20250421'.
REPLACE REGEX `(\d{4})(\d{2})(\d{2})` IN date_in WITH '$3.$2.$1'. " $1=YYYY, $2=MM, $3=DD
WRITE: / date_in. " Salida: 21.04.2025

6. Tipo C y Truncamiento

DATA text_c TYPE c LENGTH 15 VALUE 'Texto corto'.
WRITE: / 'Antes :', |'{ text_c }'|.
REPLACE 'corto' IN text_c WITH 'contenido mas largo'. " Reemplazo es mucho mas largo
WRITE: / 'Despues:', |'{ text_c }'|.

Salida:

Antes : '{Texto corto }'
Despues: '{Texto contenido}'

(El reemplazo “contenido mas largo” fue truncado a “contenido” para mantener la longitud del campo 15).

Notas Importantes / Mejores Practicas

  • Recuerde que REPLACE modifica directamente la variable. Haga una copia antes si es necesario.
  • Tenga cuidado con REPLACE en campos de longitud fija (Tipo C), ya que puede haber perdida de datos por truncamiento. Prefiera usar STRING para esto.
  • Utilice la opcion REGEX para reemplazos de patrones flexibles y poderosos.
  • Verifique sy-subrc despues de la sentencia para determinar si se realizaron reemplazos.
  • Considere la funcion replace(...) y String-Templates como alternativas modernas, especialmente cuando el valor original debe preservarse.