Sustituir 2 caracteres por uno

Todo lo relacionado con REXX en este ambiente.
Responder
dandarc

Sustituir 2 caracteres por uno

Mensaje por dandarc » 20 Ago 2008, 12:33

Hola:

Tengo que sustituir 2 caracteres por uno en una cadena, utilice la funcion TRANSLATE para relizar esto, pero no resulto lo que esperaba:

Esto es lo que necesito:
Cadena de entrada: uno$#dos$#tres
Cadena resultante: uno~dos~tres

Primero intente: TRANSLATE(uno$#dos$#tres,'~','$#')
Y el resultado fue: uno~ dos~ tres
Casi lo logre, pero los espacios entre las tildes y las palabras no los quiero.

Entonces intente: TRANSLATE(uno$#dos$#tres,,'$#','~')
Y resulto: uno~~dos~~tres
Pues me salio peor, porque me duplico las tildes.

¿ Alguien tiene idea de como lo puedo hacer ? :?:

Avatar de Usuario
hdezmm
Colaborador
Colaborador
Mensajes: 115
Registrado: 16 Jun 2007, 02:49
País: Mexico
Ciudad: Ciudad de Mexico DF
Ocupación: Técnico en Sistemas

Saludos ....

Mensaje por hdezmm » 21 Ago 2008, 17:28

inspect cadena-entrada replacing all '#' by '~'
inspect cadena-entrada replacing all '$' by '~'
Saludos desde Mexico DF
----------------------------------------------------
Lo importante no es saber ..... sino tener el telefono del que sabe .... :-))

NJB
Su anfitrion
Su anfitrion
Mensajes: 1114
Registrado: 12 Oct 2003, 16:27
País: Argentina
Ciudad: Capilla del Señor
Ocupación: System Programmer
Contactar:

Mensaje por NJB » 21 Ago 2008, 20:06

Hola

Me parece que vas por mal camino, pues el translate sirve para reemplazar una string de caracteres por otro pero ambos del mismo largo, y si el de reemplazo es mas corto pues lo llena con el caracter de pad que por default es blanco. Es exactamente lo que te pasa a ti.

Yo lo haria con parse, siempre y cuando la cantidad de reemplazos sea mas o menos baja por registro, no mas de 20.

Quedaria algo asi (ojo que no lo he probado y no tengo el manual):

PARSE VALUE entrada WITH a '$#' b '$#' c '$# d
y asi se sigue hasta la cantidad de veces que se pueda repetir el $# en el string entrada

Despues tenes que "armar" el string de salida de la siguiente manera

salida=a||~||b||~||c||~||d
y se sigue asi hasta la cantidad de campos que definiste en el parse.

Si bien no será en una sola instruccion seguramente funciona.

Espero que te sirva.

Te mando un cordial saludo
Norberto Bocalandro

Avatar de Usuario
Horacio Villa
Colaborador
Colaborador
Mensajes: 186
Registrado: 04 Dic 2003, 13:11
País: Argentina
Ciudad: Buenos Aires
Ocupación: DBA

Mensaje por Horacio Villa » 23 Ago 2008, 12:52

Adhiero a la propuesta de Norberto.
Si tu necesidad es mayor, yo suelo utilizar una rutina que la podés invocar como función externa, así: (generás un member REPLACEST)

/* REXX */
/* target: string que se quiere modificar
old : string que se desea reemplazar en target
new : string con la que se desea reemplazar old en target
*/
arg target,old,new
leno = length(old)
i = pos(old,target)
do while i > 0
target = insert(new,delstr(target,i,leno),i-1)
i = pos(old,target)
end
return target

o la incluís en tu programa, así:

replacestr: procedure
/* target: string que se quiere modificar
old : string que se desea reemplazar en target
new : string con la que se desea reemplazar old en target
*/
arg target,old,new
i = pos(old,target)
do while i > 0
target = insert(new,delstr(target,i,2),i-1)
i = pos(old,target)
end
return target

y dentro de tu programa, en ambos casos, lo invocás así:

newstr = replacest(oldstr,'$#','~')
HV

Avatar de Usuario
acevedo
Colaborador Senior
Colaborador Senior
Mensajes: 375
Registrado: 01 Abr 2005, 14:36
País: España
Ciudad: Malaga
Ocupación: Analista de desarrollo

Re: Sustituir 2 caracteres por uno

Mensaje por acevedo » 25 Ago 2008, 06:26

dandarc escribió: Esto es lo que necesito:
Cadena de entrada: uno$#dos$#tres
Cadena resultante: uno~dos~tres

Primero intente: TRANSLATE(uno$#dos$#tres,'~','$#')
Y el resultado fue: uno~ dos~ tres
Casi lo logre, pero los espacios entre las tildes y las palabras no los quiero.
SUPONIENDO que no hubiese más espacios en las variables uno dos y tres os recuerdo que los espacios intermedios en un string se pueden eliminar con la instrucción SPACE, por ejemplo, el resultado de la instrucción:

Código: Seleccionar todo

say SPACE('Hola Don Pepito',0)
sería

Código: Seleccionar todo

HolaDonPepito

Luis Miguel Martinez Ch.

Re: Sustituir 2 caracteres por uno

Mensaje por Luis Miguel Martinez Ch. » 25 Ago 2008, 14:21

Si no lo has logrado aun ....

1.- Una macro de ISPF con un change
2.- El comando sed de USS
3.- El subcomando SUB del awk en USS

dandarc

Mensaje por dandarc » 01 Sep 2008, 17:32

Gracias a todos por sus aportes,
primero intente con la idea del PARSE de norberto, pero me resulto muy dificil y no lo logre, y despues con la funcion de Horacio y me funciono a la perfeccion.

Gracias.

riloama
Colaborador
Colaborador
Mensajes: 187
Registrado: 02 Sep 2008, 18:39
Ubicación: Caracas - Veenzuela

Sustituir 2 caracteres por uno

Mensaje por riloama » 03 Sep 2008, 12:04

Hola,

Ayer me integre a Dinoland por lo que en esta primer intervencion deseo enviarles un saludo.

Estuve leyendo los ultimos posts y en lo que hace a este tema quisiera hacer un agregado.

El procedimiento enviado por Horacio resuelve la cuestion planteada por Dandarc, pero hay un caso particular en el que hay 2 respuestas posibles; este caso se plantea cuando:

1. la cadena de reemplazo esta incluida en la cadena a reemplazar
2. el reemplazo en el string genera una nueva cadena a ser reemplazada.

Para clarificar va el siguiente ejemplo:

Cadena a reemplazar: '$_'
Cadena de reemplazo: '$'

String: 'OCEANO$_______ATLANTICO'

Si aplicamos el procedimiento de Horacio, el string se transforma en

OCEANO$ATLANTICO

y esto se debe a que el procedimiento en el DO WHILE siempre inicia su analisis desde el inicio del string por lo que el reemplazo de la cadena ‘$_’ por ‘$’ genera una nueva cadena a reemplazar debido a la adyacencia de caracteres ‘_’. Esta es una respuesta posible y depende del requerimiento que se desea resolver.

Otra solucion posible a este caso es la transformación del
String: OCEANO$_______ATLANTICO

en

OCEANO$______ATLANTICO

por el simple reemplazo de la unica ocurrencia de ´$_’ por ‘$’. Esta es otra solucion posible, dependiendo como en el anterior caso de lo que sea necesario resolver.

Para realizar esto ultimo, sobre la solucion de Horacio y con su permiso, el procedimiento quedaria:

replacest: procedure
/* target: string que se quiere modificar
old : string que se desea reemplazar en target
new : string con la que se desea reemplazar old en target
*/
arg target,old,new
lo=length(old)
ln=length(new)
j = - ln + 1
i = pos(old,target)
do while i > 0
i = i + j + ln - 1
j = i
target = insert(new,delstr(target,i,lo),i-1)
i = pos(old,substr(target,i+ln ) )
end
return target

En este caso el procedimiento queda independiente de las longitudes de las cadenas old y new.

Saludos
Saludos

riloama

Avatar de Usuario
Horacio Villa
Colaborador
Colaborador
Mensajes: 186
Registrado: 04 Dic 2003, 13:11
País: Argentina
Ciudad: Buenos Aires
Ocupación: DBA

Mensaje por Horacio Villa » 03 Sep 2008, 17:20

Riloama,

no sólo va mi permiso, sino mi agradecimiento por la saludable corrección.
HV

riloama
Colaborador
Colaborador
Mensajes: 187
Registrado: 02 Sep 2008, 18:39
Ubicación: Caracas - Veenzuela

Sustituir 2 caracteres por uno

Mensaje por riloama » 03 Sep 2008, 17:25

De nada Horacio.

Pero no fue una correccion, solo un agregado.
Ambas respuestas son validas, depende de cual es el requerimiento exacto.
Saludos

riloama

Avatar de Usuario
juancle
Usuario avanzado
Usuario avanzado
Mensajes: 39
Registrado: 15 Dic 2008, 20:32
País: Argentina
Ciudad: Vicente Lopez
Ocupación: System Programmer

Re: Sustituir 2 caracteres por uno

Mensaje por juancle » 09 Feb 2009, 04:57

Ya que TRANSLATE rellena con blancos por default, se podria simplificar usando la funcion SPACE :

/*REXX*/
a=SPACE(TRANSLATE(uno$#dos$#tres,'~','$#'), 0)
say a
exit

Saludos
Juan

Avatar de Usuario
jlanderos
Usuario
Usuario
Mensajes: 18
Registrado: 26 Sep 2017, 18:21
País: México
Ciudad: CDMX
Ocupación: IT Specialist

Re: Sustituir 2 caracteres por uno

Mensaje por jlanderos » 27 Dic 2017, 03:05

Hola:

Tropezandome con un problema similar al que se comenta en este foro. Por el motivo de armar la estructura de un correo con formato HTML y la necesidad de sustituir símbolos propios de dicho formato tuve que hacer una función para ello. Aquí dejo mi contribución exacta como se realizó el test para el ajuste. Sin embargo, esto puede ser fácilmente adaptable a las necesidades del que lo necesite.

Código: Seleccionar todo

/* REXX */

Text.0 = 2
Text.1 = '+CSQX526E <QMGR CSQXRESP Message sequence error for channel'
Text.2 = ' AIXMVS.G1QMD001.FIN, sent=100 expected=1'

do Ix = 1 to Text.0
  Add_Mail(StrReplace(Text.Ix))
end Ix
exit

StrReplace: procedure                                  
parse arg String                                       
                                                       
Array. = ''                                            
Array.1 = '< <'                                     
Array.2 = '> >'                                     
                                                       
Ix = 1                                                 
do until Array.Ix = ''                                 
  parse value Array.Ix with OldLetter NewLetter .      
  WidthOldL = length(OldLetter)                        
  IxOldLetter = pos(OldLetter, String)                 
  if IxOldLetter > 0 then do                           
    String = delstr(String, IxOldLetter, WidthOldL)    
    String = insert(NewLetter, String, IxOldLetter - 1)
  end                                                  
  else                                                 
    Ix = Ix + 1                                        
end                                                    

return string
Saludos y suerte.

El camino de 1,000 kilómetros inicia con un solo paso. :arriba:

Responder