domingo, 22 de julio de 2012

Cadenas

Si deseamos trabajar con cadenas, nuestro acometido será muy similar al de python. Por ejemplo, si queremos unir dos cadenas simplemente usaremos el símbolo "+". Si lo que deseamos es obtener una subcadena usaremos los corchetes []. En el interior de los corchetes la sintaxis es la siguiente [inicio:fin]. Por lo tanto si queremos crear una subcadena con los dos primeros caracteres haremos lo siguiente [0:2]

[indent=4]
a: string
b: string 
c: string
init
    a="hola."
    b=",mundo"
    a= a[0:4]     //transformaremos a en hola sin punto
    c= a+b
    print c


Ojo!! Si lo que deseamos es sacar un solo caracter con formato tipo "char" usaremos esto : cadena[posición]. Lo cual no podremos imprimir con un simple print puesto que solo sirve para cadenas.
Ahora bien tendrémos que especificar que es un Char de este modo "%c",a[0]

Ejemplo:

[indent=4]
a: string
init
    a="hola"
    print a[0:1]    //Sacamos la "h" en forma string
    print "%c",a[0] //especificamos que "h" será un char

    print a[0:a.length] //Escribe todo hasta la longitud total
    print a[0:a.index_of("o",0)+1]  // imprime hasta la o
    print print a.replace("h","m") // escribe "mola" en vez de "hola"


Pero como en Python también tenemos la opción de separar una cadena dados ciertos separadores o unirla.

Ejemplo:

[indent=4]
a: string
f : new array of string
init
    a="hola que tal estas"
    f=a.split(" ")
    for i in f
        print i  // se imprimirá cada palabra por separado
   
 
//Después se pueden unir usando joinv, las uniremos con ":"

    m= m.joinv(":",f)
    print m



Glib aporta una serie de métodos para tratar las cadenas como UTF8. Ejemplo:

[indent=4]
a: string
f : new array of string
init
    a="á"
    print a

    print a.length // El valor es 2 puesto que cuenta los valores crudos.
    print a.char_count() // Este método se usa para Unicode. el resultado es 1.


Mayormente usaremos char_count para así poder usar unicode sin problemas.
Python sigue siendo bastante más sencillo para usar unicode. En este ejemplo tomaré una cadena unicode y la imprimiré de unicode en unicode.
Estas son las nuevas funciones que he usado: 
a.get_char(int) Toma un unichar de la cadena en la posición cruda int
a.index_of_nth_char(int) Indexa la posición Unicode de int, no usa la cruda.
a.char_count() Cuenta los caracteres unicode de la cadena.
He empleado también StringBuilder http://references.valadoc.org/#!api=glib-2.0/GLib.StringBuilder que nos puede servir para conformar cadenas a través de variables de tipo caracter o unicode-caracter





a: string
i: int

def toma_cadena (a:string,i :int ):string
    b: string
    var bu = new StringBuilder ();
    bu.append_unichar(a.get_char(a.index_of_nth_char(i)))
    b=bu.str
    return b
def longitud (a:string):int
    return a.char_count()

init
    a="1h2á3o4ó5ú"
    print "%i",longitud (a) 
   
    for i =0 to (longitud(a))
        stdout.printf( "%s\n",toma_cadena(a,i))
    


¿Que quiero decir con posición cruda y unicode?

Tenemos que entender que el unicode es una forma de notar todos los caracteres que están fuera de ASCII. Es decir los caracteres con acentos, dieresis, etc.
Estos caracteres toman formas crudas como \x3 por ejemplo. Por lo tanto ocuparán diferente espacio; "a" ocupa un espacio pero "á" ocupa dos. Puesto que la notación unicode para la acentuada ocupa dos espacios. Tenemos que tener en cuenta que dentro de UTF-8,16 o 32 (unicode) hay caracteres rusos, chinos etc. Y Ascii solo tiene 256. Es por eso que para el español se necesita el unicode puesto que los ingeleses no incluyeron los acentos dentro de ascii.   Ahora bien cuando hablo de posición o longitud cruda de "á" hablo de 2 y cuando hablo de longitud unicode de "á" diré 1. Lógicamente yo siempre usaré unicode por la cuenta que me trae. Eso quiere decir que muchas de las ventajas de usar corchetes desaparecen puesto que usan las cadenas crudas y no unicode.
Por lo tanto para similar los corchetes [] yo crearía las siguientes funciones para facilitar mi código. Aunque se podría mejorar para incluir las funciones de resta -1 para coger todo menos el último carácter, etc. Pero aquí no me voy a liar.

[indent=4]
a: string
i: int

def toma_cadena (a:string,i :int,f:int=-1):string
    b: string
    
    var bu = new StringBuilder ();
    if f==-1
        bu.append_unichar(a.get_char(a.index_of_nth_char(i)))
        b=bu.str
    else
        if f>0
            var p=i
            while p<f
                bu.append_unichar(a.get_char(a.index_of_nth_char(p)))
                p++
            b=bu.str
        else
            b=""
    return b

def longitud (a:string):int
    return a.char_count()


init
    a="áéíóú"
    stdout.printf ("%i\n",longitud (a))
    stdout.printf( "%s\n",toma_cadena(a,2,4))
   



No hay comentarios:

Publicar un comentario