Página 1 de 1

Compara cadenas

Publicado: 02 Mar 2010, 20:03
por Souf
Hola,
Tengo un pequeño problema con una macro que estoy realizando.
La macro trata unos datos de un excel, y luego los mete en una aplicación, y he logrado que funcione todo correctamente, excepto en un paso que comprueba que los datos que lee de un text-box son iguales a los que tiene en una variable (que lee de un excel).
Los datos del text-box los lee correctamente, y los del excel también, pero a la hora de compararlos, tengo problemas con las mayúsculas y minúsculas.
Tras mucho buscar, no encuentro ninguna función que me pase una cadena a mayúsculas o a minúsculas (ni upper ni lower) para comparar ambas cadenas.
¿Que función de autoit me podría comparar las cadenas sin tener en cuenta mayúsculas y minúsculas?
Gracias

Re: Compara cadenas

Publicado: 02 Mar 2010, 20:38
por Nahuel
Pues haciendo una comparación normal:

Código: Seleccionar todo

$cadena1 = $cadena2
No tiene en cuenta las mayúsculas. Si usás == si:

Código: Seleccionar todo

$cadena1 == $cadena2
En este caso es "case sensitive".

Ej:

Código: Seleccionar todo

If "hola" = "HoLa" Then MsgBox(0,"Sin comparar mayusculas","Son iguales")
If "hola" == "HoLa" Then MsgBox(0,"Comparando mayusculas","Son iguales")
Se me ocurre que tu problema tiene que ver con los espacios. Probá usando

Código: Seleccionar todo

StringStripWS($cadena,3)
para cada cadena. Algo así:

Código: Seleccionar todo

StringStripWS($cadena1,3) = StringStripWS($cadena2,3)
el valor 3 le dice que elimine tanto espacios al principio como al final de la cadena. También podés usar el valor 8 que elimina todos los espacios y lo convertiría en una cadena algoasicomoesta.

Si aún querés saber lo que preguntás, estas son las funciones:

Código: Seleccionar todo

StringLower ( "string" )
StringUpper ( "string" )
Saludos

Re: Compara cadenas

Publicado: 02 Mar 2010, 22:34
por Souf
Gracias Nahuel.
La comparación con == no me ha servido, pero sí la función
StringUpper ( "cadena" )
Ahora ya solo me falta quitarme los acentos y listo!
Muchas Gracias

Re: Compara cadenas

Publicado: 03 Mar 2010, 09:03
por Ximorro
Ay ay ay con lo que se lo ha currado Nahuel creo que le has leído muy rápido :smt003

La comparación == no te sirve porque es la que distingue las mayúsculas, la que te tiene que servir es la =

:smt002

Re: Compara cadenas

Publicado: 03 Mar 2010, 13:19
por Souf
Ximorro escribió:Ay ay ay con lo que se lo ha currado Nahuel creo que le has leído muy rápido :smt003

La comparación == no te sirve porque es la que distingue las mayúsculas, la que te tiene que servir es la =

:smt002
No, la = es la que usaba, y no me valía, yo probé también con ==, por si no lo hubiera puesto bien.
Al final con la función StringUpper me ha funcionado (busqué por upper en la ayuda y no encontré funciones de strings, ya veo que no lo encontré, porque sí que existía).
Ahora tengo que hacer una función para que me quite las letras con tildes y ya estará.
Saludos

P.D.: Gracias a todos por vuestra ayuda, con los manuales, y las respuestas a algunas preguntas, he logrado hacer lo que quería tenindo toda la info para ello (excepto la función stringupper)

Re: Compara cadenas

Publicado: 03 Mar 2010, 13:47
por Ximorro
Vaya, pues qué raro que no vaya la "=" si es cosa de mayúsculas...

Por ejemplo la expresión ("ABáñ" = "abÁÑ") me da TRUE, y eso que le meto hasta acentos y ñ.

Pues ya por curiosidad, dinos alguna cadena que no vaya con "=" y sí con StringUpper, a ver qué casos hay que tener en cuenta...

Por cierto, para lo de los acentos mírate StringReplace, me temo que tendrás que hacerlo un poco a mano. No sé si con StringRegExpReplace se podrá hacer más compacto, hay gente que con expresiones regulares hace verdaderas maravillas...

Re: Compara cadenas

Publicado: 03 Mar 2010, 16:37
por Nahuel
Que extraño... si respondí a este post antes que Ximorro diciendo justamente que no entendió lo que quise decirle... Sigo insistiendo que se trata de un problema de espacios. En lugar de convertir todo a mayúsculas, usá:

Código: Seleccionar todo

StringTrimWS($Cadena1,3) = StringTrimWS($Cadena2,3)
Lo has probado? Tampoco hay problemas con los acentos o las ñ's.

Re: Compara cadenas

Publicado: 04 Mar 2010, 11:00
por Ximorro
Pero si lo raro es que dice que con StringUpper le funciona, si fuera cosa de espacios con eso tampoco funcionaría...

A ver si nos pasa algún ejemplo de texto concreto que falle y miramos qué tiene...

Re: Compara cadenas

Publicado: 10 Mar 2010, 14:43
por Souf
Ximorro escribió:Pero si lo raro es que dice que con StringUpper le funciona, si fuera cosa de espacios con eso tampoco funcionaría...

A ver si nos pasa algún ejemplo de texto concreto que falle y miramos qué tiene...
Ya lo cambié y me funcionó, puse banderitas para que mostrara los valores de las variables.
De todas maneras, ya logré que funcionara, con el upper.
Nahuel escribió:Que extraño... si respondí a este post antes que Ximorro diciendo justamente que no entendió lo que quise decirle... Sigo insistiendo que se trata de un problema de espacios. En lugar de convertir todo a mayúsculas, usá:

Código: Seleccionar todo

StringTrimWS($Cadena1,3) = StringTrimWS($Cadena2,3)
Lo has probado? Tampoco hay problemas con los acentos o las ñ's.
Ahora lo probaré (esta tarde), puede realmente que el problema fuera los espacios, y lo confundiera..., aunque si fuera así, con el upper no tendría que haber funcionado... :S
Gracias por la ayuda... ;)

EDITO:
Ya he logrado que me funcione todo, haciendo una funcion con el replace (que remplaza las letras con acento, por la misma letra sin acento), y quitando los espacios de toda la cadena, pero no he podido simular el fallo en la evaluación de cadenas que comentaba más arriba.
Primero he pasado a mayúsculas, luego le he quitado los espacios, y por último la función de quitar acentos (las tres concatenadas)
Por mi parte doy este hilo como cerrado, espero que la info de aquí pueda ayudar a otras personas que tengan mis dudas/problemas.
Saludos

Re: Compara cadenas

Publicado: 11 Mar 2010, 13:14
por Ximorro
Me alegro de que lo hayas solucionado, aunque realmente no sabemos qué pasaba. Quiero decir que no está claro que fallara el operador "=", no parece que haya casos en los que se comporte diferente a compara con StringUpper ¿no? Esa es la curiosidad que me ha quedado sin resolver.

¿El problema sería entonces los espacios en blanco, que has solucionado con StringTrimWS? ¿y "=" y "comparar con StringUpper" es realmente equivalente?

Re: Compara cadenas

Publicado: 30 Sep 2011, 13:21
por jamaro
He buscado en este y otros foros y sigo en este hilo porque tiene algo que ver mi pregunta.

Se trata de reemplazar en una cadena caracteres especiales con acentos (tildes) a caracteres sin acentos.

En un foro de PHP he visto que en ese lenguaje se puede hacer de una manera muy simple con una única función:

Código: Seleccionar todo

$limpiar = strtr($cadena, "áäàéëèíïìóöòúüùñ", "aaaeeeiiiooouuuñ");  
He estado buscando y no encuentro nada similar en Autoit.

En un hilo del foro inglés he encontrado un código que sirve para convertir los caracteres, pero al utilizarlo veo que no hace correctamente los caracteres con tilde y mayúsculas.

Utilizando la cadena:
Este texto tiene caracteres con acentos y la función los convierte: aáÁA Séville, Ééeë

Código: Seleccionar todo

$sCadena="Este texto tiene caracteres con acentos y la función los convierte: aáÁA Séville, Ééeë"

convcar($sCadena)


Func ConvCar($sStr)

	Local $aSearch = StringSplit("Š,Œ,Ž,š,œ,ž,Ÿ,¥,µ,À,Á,Â,Ã,Ä,Å,Æ,Ç,È,É,Ê,Ë,Ì,Í,Î,Ï,Ð,Ñ,Ò,Ó,Ô,Õ,Ö,Ø,Ù,Ú,Û,Ü,Ý,ß,à,á,â,ã,ä,å,æ,ç,è,é,ê,ë,ì,í,î,ï,ð,ñ,ò,ó,ô,õ,ö,ø,ù,ú,û,ü,ý,ÿ", ",", 2)
	Local $aReplace = StringSplit("S,O,Z,s,o,z,Y,Y,u,A,A,A,A,A,A,A,C,E,E,E,E,I,I,I,I,D,N,O,O,O,O,O,O,U,U,U,U,Y,s,a,a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,o,n,o,o,o,o,o,o,u,u,u,u,y,y", ",", 2)

	; Sistema reemplazando todas las letras en la cadena
	For $i = 0 To Ubound($aSearch) -1
		$sStr = StringReplace($sStr, $aSearch[$i], $aReplace[$i],1)
	Next

       ConsoleWrite($sStr)
EndFunc
Devuelve: Este texto tiene caracteres con acentos y la funciOn los convierte: aaÁA SEville, eéeE


He probado con otro método, reemplazando cada una de las letras de la cadena inicial, pero parece que tampoco funciona:

Código: Seleccionar todo

$sCadena="Este texto tiene caracteres con acentos y la función los convierte: aáÁA Séville, Ééeë"

convcar($sCadena)



Func ConvCar($sStr)

	Local $aSearch = StringSplit("Š,Œ,Ž,š,œ,ž,Ÿ,¥,µ,À,Á,Â,Ã,Ä,Å,Æ,Ç,È,É,Ê,Ë,Ì,Í,Î,Ï,Ð,Ñ,Ò,Ó,Ô,Õ,Ö,Ø,Ù,Ú,Û,Ü,Ý,ß,à,á,â,ã,ä,å,æ,ç,è,é,ê,ë,ì,í,î,ï,ð,ñ,ò,ó,ô,õ,ö,ø,ù,ú,û,ü,ý,ÿ", ",", 2)
	Local $aReplace = StringSplit("S,O,Z,s,o,z,Y,Y,u,A,A,A,A,A,A,A,C,E,E,E,E,I,I,I,I,D,N,O,O,O,O,O,O,U,U,U,U,Y,s,a,a,a,a,a,a,a,c,e,e,e,e,i,i,i,i,o,n,o,o,o,o,o,o,u,u,u,u,y,y", ",", 2)

	; Sistema buscando cada letra de la cadena en la matriz y reemplazándola
	For $i=1 to StringLen($sStr)
		$sLetraBuscada=StringMid($sStr,$i,1)
		$nPosicionEncontrada=_ArraySearch($aSearch,$sLetraBuscada,0,0,1,1)
		ConsoleWrite("La letra " & $i & " es la " &  $sLetraBuscada & " Encontrada en la posición: " & $nPosicionEncontrada & @CRLF)

		If $nPosicionEncontrada<>-1	Then	; Se ha encontrado
			$sStr=StringReplace($sStr,$sLetraBuscada,$aReplace[$nPosicionEncontrada])
		EndIf

	Next
	ConsoleWrite($sStr)
EndFunc
Devuelve: Este texto tiene caracteres con acentos y la funcion los convierte: aaaA Seville, eeee

Como se puede observar, tanto en uno como en otro no funciona bien con todos los caracteres. He probado a cambiar el orden de los caracteres en las matrices otriginales, y a cambiar "Case Sensitive", pero tampoco he llegado a una solución adecuada.

Quizás no se pueda hacer, o quizás sea una tontería, pero ahí lanzo una nueva llamada a la ayuda :smt026

Re: Compara cadenas

Publicado: 30 Sep 2011, 14:02
por Ximorro
Es que me parece que ha habido una confusión al usar StringReplace, el tercer parámetro es las veces que se reemplaza, no el caso sensitivo.
Así que
$sStr = StringReplace($sStr, $aSearch[$i], $aReplace[$i],1)
cambia SOLO UN carácter, y encima NO ES caso sensitivo.

Lo correcto es decirle que cambie todos los caracteres encontrados, y que sea caso sensitivo, si pones
$sStr = StringReplace($sStr, $aSearch[$i], $aReplace[$i],0,1)
el primer programita ya funciona perfectamente.

Y sí, es una faena que AutoIT no tenga sustitución múltiple, porque así tenemos que leer todo el texto tantas veces como sustituciones hayamos contemplado. En el ejemplo es una simple frase pero para cambiar un archivo de texto de varias megas...

Para casos de textos grandes creo que lo mejor será hacerlo al revés: leer el archivo letra a letra y para cada letra mirar si hay que sustituirla. Lo interesante de hacerlo así es que en vez de mirar el array de intercambios cada vez, se puede montar un diccionario con el objeto Scripting.Dictionary de Windows (es una tabla hash, por si sabes lo que es eso) que tiene acceso mega-rápido.

Re: Compara cadenas

Publicado: 30 Sep 2011, 14:09
por jamaro
Como siempre muchas gracias (¡esos dichosos parámetros!).


Ximorro escribió: Para casos de textos grandes creo que lo mejor será hacerlo al revés: leer el archivo letra a letra y para cada letra mirar si hay que sustituirla.
Es lo que intentaba hacer con la segunda opción :-)
Ximorro escribió: Lo interesante de hacerlo así es que en vez de mirar el array de intercambios cada vez, se puede montar un diccionario con el objeto Scripting.Dictionary de Windows (es una tabla hash, por si sabes lo que es eso) que tiene acceso mega-rápido.
No sé que es eso :-)

Re: Compara cadenas

Publicado: 30 Sep 2011, 14:41
por chekok
Una tabla hash o mapa hash es una estructura de datos que asocia llaves o claves con valores. La operación principal que soporta de manera eficiente es la búsqueda: permite el acceso a los elementos (teléfono y dirección, por ejemplo) almacenados a partir de una clave generada (usando el nombre o número de cuenta, por ejemplo). Funciona transformando la clave con una función hash en un hash, un número que la tabla hash utiliza para localizar el valor deseado.


Ejemplo de tabla hash.
Las tablas hash se suelen implementar sobre vectores de una dimensión, aunque se pueden hacer implementaciones multi-dimensionales basadas en varias claves. Como en el caso de los arrays, las tablas hash proveen tiempo constante de búsqueda promedio O(1),1 sin importar el número de elementos en la tabla. Sin embargo, en casos particularmente malos el tiempo de búsqueda puede llegar a O(n), es decir, en función del número de elementos.
Comparada con otras estructuras de arrays asociadas, las tablas hash son más útiles cuando se almacenan grandes cantidades de información.
Las tablas hash almacenan la información en posiciones pseudo-aleatorias, así que el acceso ordenado a su contenido es bastante lento. Otras estructuras como árboles binarios auto-balanceables son más rápidos en promedio (tiempo de búsqueda O(log n)) pero la información está ordenada en todo momento.

Las operaciones básicas implementadas en las tablas hash son:
inserción(llave, valor)
búsqueda(llave) que devuelve valor
La mayoría de las implementaciones también incluyen borrar(llave). También se pueden ofrecer funciones como iteración en la tabla, crecimiento y vaciado. Algunas tablas hash permiten almacenar múltiples valores bajo la misma clave.
Para usar una tabla hash se necesita:
Una estructura de acceso directo (normalmente un array).
Una estructura de datos con una clave
Una función resumen (hash) cuyo dominio sea el espacio de claves y su imagen (o rango) los números naturales.

Fuente: Wikipedia. http://es.wikipedia.org/wiki/Tabla_Hash_(programación)

Re: Compara cadenas

Publicado: 03 Oct 2011, 08:30
por Ximorro
Luego os pondré un ejemplo, pero al final mi gozo en un pozo porque lo más rápido ha sido lo de usar StringReplace muchas veces. La lentitud a la hora de interpretar el código AutoIt compensa negativamente lo que se pueda ganar con el nuevo algoritmo...

Resulta que leer la cadena (o fichero de texto) carácter a carácter es lentísimo, me temo que AutoIt no está preparado para esto.
Desde luego con el diccionario es mucho más rápido que con matrices, luego os lo pongo y así veis cómo se usa desde AutoIt, pero sigue siendo más lento que ejecutar directamente la función compilada StringReplace.

Re: Compara cadenas

Publicado: 03 Oct 2011, 13:43
por Ximorro
El estudio que os comento está aquí:
http://www.emesn.com/autoitforum/viewto ... f=3&t=2895