.. strings: Manejo de String ================= Complementando con lo que se definió en los tipos de `datos de texto`_ .. _`datos de texto`: programas.html#tipo-texto En Python podemos delimitar un "string" usando las comillas simples, las comillas dobles, incluso triples triple comillas para fragmentos largos. Algo importante, los dos primeros casos son exactamente iguales, no hay diferencia visual práctico en su uso y podemos usar uno u otro indistintamente, o podemos elegir en función de que haya comillas simples o dobles dentro de nuestra cadena. Por ejemplo, si dentro de nuestra cadena hay comillas simples, podemos delimitar la cadena con comillas dobles, para evitar conflictos. Ejemplo .. literalinclude:: ../examples/string/string.py La salida esperada para el ejemplo anterior es la siguiente: .. code-block:: text Hola ' Mundo Otro " Hola Mundo En un lugar ' de la mancha" de cuyo nombre no quiero acordarme Analizando las variables en primer lugar "texto" y "texto2" su valor contiene comillas simples y dobles entremedio de las cadenas definidas, permitiendo que sean visualizada en la salida. Esto dice que en el caso de necesitar mostrar comillas simple o doble en la salida podemos incluirlas dentro de la cadena del modo expuesto. La variable "texto3" ha sido declarada con triple comillas, esto nos permite mostrar en pantalla textos más extensos como lo son párrafos. Secuencia de escape ------------------- En Python (como en otros lenguajes) tiene caracteres especiales que se interpretan dentro de una cadena de texto antecedidos por un 'backslash' y un caracter que realizará un formateo al "string" antes de mostrarlo en pantalla. A esto se denomina una secuencia de escape. Ejemplo .. code-block:: python a = "Hola \n Mundo" print(a) La salida esperada es la siguiente en donde podemos observar el salto de linea: .. code-block:: text Hola Mundo En la siguiente tabla se representan algunos caracteres especiales .. code-block:: text | ----------------------------------- | Secuencia | | | Escape | Resultado | ----------------------------------- | \n | Salto de linea | ----------------------------------- | \t | Tabulado horizontal | ----------------------------------- | \v | tabulado vertical | ----------------------------------- | \b | Borra un espacio | ----------------------------------- | \f | Formfeed | ----------------------------------- | \r | Retorna al margen | ----------------------------------- Existen muchos caracteres especiales para el manejo de string, la lista puede consultarse en la siguiente url: `https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals`_. .. _`https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals`: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals Mayúsculas, Minúsculas y Capital -------------------------------- No es lo mismo una 'A' que una 'a', por lo que se hace imperioso en muchas ocasiones tener que 'normalizar' los textos a manejar para no tener problemas. Un ejemplo de lo anterior son los tipos de búsquedas para el caso de no conocer el estilo del texto en su forma. Es aquí una buena opción transformar el texto ya sea a mayúsculas, minúsculas o utilizar letra capital. En `Python` existen funciones que logran realizar la transformación del texto: * upper() para convertir a mayúsculas * lower() para minúsculas * capitalize() para letra capital o mayúscula inicial. Estás funciones son propias de todo elemento de tipo "str". Ejemplo .. literalinclude:: ../examples/string/string11.py La forma de utilizar es llamar a la función que se desea instanciar utilizando un punto y seguido del nombre de la función. La salida del ejemplo es la siguiente: .. code-block:: text HOLA MUNDO hola mundo Hola mundo Formateo y completado con variables ----------------------------------- Para complementar cadenas de "string" con otras variables, como por ejemplo números, hay cuatro formas de como hacerlo: * Utilizando el operador "%" * Usando el método "format()" * Usando f-string (solo para Python > 3.6) * Concatenando utilizando el método join() Operador % ^^^^^^^^^^ El operador "%" es la forma más conocida y tradicional de complementar o concatenar "string" con otras variables, pues es la forma que muchos lenguajes utilizan para realizar la acción. Sintaxis .. code-block:: python variable = 'string %[formato]' %variable En donde %[formato] complementará el "string" con la variable declarada. Ejemplo: .. code-block:: python print("El valor es %d" %11) print("Los valores son %d y %d" %(11, 33)) print("Muestro un entero de 5 cifras por delante %5d" %11) print("Muestro un numero real (float) con dos decimales %.2f" %10.2313242) print("Mi nombre es %s " %"pepito") La salida es la siguiente: .. code-block:: text El valor es 11 Los valores son 11 y 33 Muestro un entero de 5 cifras por delante 11 Muestro un numero real (float) con dos decimales 10.23 Mi nombre es pepito Hay que notar que después del signo "%" viene una letra (en el ejemplo se usaron d, f y s), esto representa al formato de la variable que se utilizará. A continuación en una tabla se muestran todos los formatos disponible por Python y aplica también para otros lenguajes de programación. .. code-block:: text ---------------------------------------------------------------- | %c | un char (caracter) | ---------------------------------------------------------------- | %d | un entero con signo en notación de base decimal | ---------------------------------------------------------------- | %i | un entero con signo | ---------------------------------------------------------------- | %e | reales((pseudoreales como double)) en notación científica | | indicando el exponente con "e" | ---------------------------------------------------------------- | %E | reales((pseudoreales como double)) en notación científica | | indicando el exponente con "E" | ---------------------------------------------------------------- | %f | formato de punto flotante | ---------------------------------------------------------------- | %g | la opción más corta entre "%e" y "%f" | ---------------------------------------------------------------- | %G | la opción más corta entre "%E" y "%F" | ---------------------------------------------------------------- | %o | un entero sin signo en notación de base octal | ---------------------------------------------------------------- | %s | una cadena de caracteres | ---------------------------------------------------------------- | %u | un entero sin signo | ---------------------------------------------------------------- | %x | un entero sin signo en notación de base hexadecimal, | | usando minúsculas para los dígitos extendidos | ---------------------------------------------------------------- | %X | un entero sin signo en notación de base hexadecimal, | | usando mayúsculas para los dígitos extendidos | ---------------------------------------------------------------- Método format() ^^^^^^^^^^^^^^^ El método "format()" es una función que nos ayudara a controlar las cadenas de texto. Su forma es poner llaves '{}' en el "string" para posicionar el valor de una variable que pasamos como parámetros a la función. Sintaxis .. code-block:: python texto = "texto {}".format(variable) En el lugar de las {} irá el valor de la variable que ha sido pasada como parámetro al método "format()". Ejemplo .. literalinclude:: ../examples/string/string12.py La salida linea a linea es la siguiente .. code-block:: text El valor es 11 El valor es 11.3456 Los valores son 1, 2 y 3 Los valores son 3, 2 y 1 200 y 11 Valor formateado 77.64 Hay varias apreciaciones respecto al ejemplo. La primera refiere al tipo de los datos de las variables. Para "format()" el tipo de datos que pasamos es indiferente, siempre intentará concatenar y lo transformará de modo automático a tipo texto no importando si el tipo es numérico u otro. La segunda apreciación es la posición de las variables; si observamos la cuarta linea las llaves está compuestas por números. Esos número refieren a la posición de los parámetros que se han pasado al método "format()", por lo que en primer lugar se incluye el parámetro en posición 2, luego en posición 1 y termina el formateo de la cadena de caracteres utilizando el parámetro en la posición 0. La ultima apreciación son las variables puestas en la quinta linea del ejemplo. Cada llave está compuesta por una variable en su interior (maria y juan), en donde esos valores corresponden a los valores de los parámetros que han sido declarados para el método "format()". F-String ^^^^^^^^ "F-string" o 'string literal format' es un "string" precedido por una letra f. Podemos poner variables entre llaves que serán reemplazados por los valores de las variables que hayan sido declaradas previamente. Sintaxis .. code-block:: python texto = f"texto {variable}" En donde variable es el valor a incluir en la cadena de texto. Ejemplo: .. literalinclude:: ../examples/string/string13.py La salida es: .. code-block:: text El valor es 132.456 El valor es: 132.46 Al igual que el método "format()" es indiferente el tipo de datos que tenga la variable, pues se intentará siempre transformar a un tipo texto para concatenar el "string". Método join() ^^^^^^^^^^^^^ El método "join()" proporciona una forma flexible de crear cadenas a partir elementos iterables. La forma de realizar la acción es uniendo cada elemento de como si fuera una lista, cadena y/o tupla mediante un separador. El elemento (variable) de tipo string puede llamar al método "join()" y el resultado es la cadena concatenada. Sintaxis .. code-block:: python string.join(iterable) Los parámetros de la función join es una lista y sería similar a declarar lo siguiente .. code-block:: python variables = [variable1, variable2, variableN] texto = "".join(variables) Ejemplo .. code-block:: python texto = " ".join(["Hola", "Mundo"]) print(texto) La salida del ejemplo es la siguiente .. code-block:: text Hola Mundo Hay que tener en cuenta que el texto inicial del ejemplo es un espacio en blanco, esto permite que los elementos 'Hola Mundo' contenga un espacio de separación entre palabras. .. code-block:: python numeros = ['1', '2', '3', '4'] texto = ', ' print(texto.join(numeros)) La salida del ejemplo es la siguiente .. code-block:: text 1, 2, 3, 4 Acá el separador no es solo un espacio, si no que también se incluye una coma (,). Recorrer Strings ---------------- Los String son tipo de datos iterables y entra en la razón de que es una lista o una cadena de caracteres. La teoría menciona que podemos recorrer cualquier cadena (lista) de texto utilizando cualquier ciclo y acceder a cada uno de los caracteres que lo componen. Ejemplo .. literalinclude:: ../examples/string/string2.py También al tratarse de un objeto iterable podemos acceder directamente al caracter deseado indicando la posición del elemento partiendo desde el valor cero. .. code-block:: python texto = "Hola Mundo" print(texto[2]) print(texto[6]) print(texto[-1]) La salida esperada es: l, M y o Obtiene Largo ------------- Para obtener el largo de una cadena de texto se utiliza la función "len()" Ejemplo .. code-block:: python texto = "Hola Mundo" print(len(texto)) La salida esperada es 10 Substring --------- Un "substring" es un "string" obtenido de un "string". Es un 'pedazo' de él y para crearlo podemos establecer los rangos necesarios recordando siempre que el primer elemento del "string" es cero. Sintaxis .. code-block:: python subcadena = texto[indice_inicial:indice_final] Ejemplo .. literalinclude:: ../examples/string/string3.py La salida espera para el ejemplo es la siguiente: .. code-block:: text 1: ol 2: Hol 3: Mundo 4: un 5: undo 6: Hola Mun Algunas apreciaciones, la primera refiere a la linea numero 2 del ejemplo, en donde no tiene 'indice inicial' y solo presenta 'indice_final', esto `Python` lo entiende como la posición inicial, o sea cero y sería símil a declarar "[0:3]". Otra apreciación sería la linea tres del ejemplo, que es exactamente opuesto a la linea dos, pues no tiene indice final. `Python` asumirá como la posición final del string, y es igual que realizar la siguiente declaración: "[4: len(texto)]". La ultima apreciación del ejemplo serían las lineas que contienen indices negativos. Esto significa que el texto será leído desde derecha a izquierda, en donde por ejemplo "texto[-4:]" quiere decir que partirá desde el elemento 4 de derecha a izquierda hasta el inicio del texto. Búsqueda dentro de strings -------------------------- Al ser una cadena de texto un objeto iterable da la posibilidad de realizar búsquedas de elementos, coincidencias dentro de un "strings". in ^^ La forma típica que podemos encontrar en `Python` para realizar búsqueda es utilizar el operado `in`_, que nos retornará un valor booleano (True o Falso). Será "True" en caso de encontrar el elemento buscado y "False" en caso de no existir coincidencia. .. _in: operadores.html#operador-de-existencia Sintaxis .. code-block:: python criterio in texto Ejemplo .. literalinclude:: ../examples/string/string4.py Las dos primeras instancias serán verdaderas porque sí se encuentran esos caracteres ('o' y 'Hola') en la cadena, mientras que las siguientes dos instancias son falsas, pues no existen los caracteres 'p' y 'll' en la cadena de texto. El operador "in" es posible incluirlo dentro una estructura de condición ("if"), para que en el caso de encontrar o no encontrar el caracter deseado realice una acción en particular. Ejemplo .. code-block:: python if "la" in texto : print ("Ok existe la") find() ^^^^^^ Otro modo de búsqueda es utilizar la función "find()" que a diferencia de la función "in" esta devuelve el índice en donde se encontró la coincidencia. Ejemplo .. literalinclude:: ../examples/string/string5.py El resultado esperado es 0 para la primera salida, pues es en la posición cero (0) es donde comienza coincidencia. Para la segunda linea la salida esperada es 5, pues es el mismo caso de la primera salida, la coincidencia comienza en el quinto caracter. Es posible entregar rangos de búsqueda al interior de una cadena de texto. Ejemplo .. literalinclude:: ../examples/string/string6.py En este caso, el segundo parámetro de la función "find()" es un entero que permite fraccionar el texto y posiciona en cursor de búsqueda en la posición declarada (número 3). La primera salida nos devolverá un -1 (menos uno). Este resultado significa que no ha sido encontrada ninguna coincidencia ya que al iniciar la búsqueda en la posición tres (3) el texto ha sido fraccionado y en lugar de buscar sobre un "Hola Mundo" lo que hace sobre un texto con valor " Mundo". Por el contrario la salida dos, sí encuentra coincidencia y el resultado devuelto es el número 5. Si queremos acotar un mayor modo nuestra cadena de "string", podemos agregar un tercer parámetro a la función "find()" que permita crear el rango entre dos posiciones, por ejemplo .. literalinclude:: ../examples/string/string7.py Acá el string de 'Hola Mundo', se ve reducido a solo cinco elemento y quedará en 'Hola ' para ser evaluado. En este caso la primera salida encontrará un resultado que será 0, pues desde esa posición encuentra la coincidencia. La segunda es -1 pues no ha encontrado coincidencia. Cuando se enfrenta a más de una coincidencia para elementos repetidos es un problema y quizás habrá que abordar estrategias. Ejemplo .. literalinclude:: ../examples/string/string8.py Utilizar solo la función "find()" puede ser insuficiente, por lo que se puede intentar con "rfind()" que es idéntico en su uso a la función "find()", pero su acción es recorrer la cadena de "string" de forma inversa, o sea de derecha a izquierda. La salida espera es: 2 y 24 pero claramente no es suficiente, pues existen tres patrones de coincidencia. Otra estrategia para enfrentar el problema analizar cuantas coincidencias existen en la cadena de "string". Para esto es posible utilizar la función "count()". Su uso es igual al método "find()". Ejemplo .. literalinclude:: ../examples/string/string9.py La salida espera es 3, 2, 1 startswith y endswith ^^^^^^^^^^^^^^^^^^^^^ Una última forma de como podemos buscar o analizar texto es utilizando las funciones "startswith" y "endswith". Son funciones más sencilla y limitadas porque solo analizan principio y fin de una cadena de caracteres. El método "startswith" se utiliza para analizar si el "string" comienza con determinado patrón y en caso de coincidir se devolverá un valor "True" y en caso contrario el retorno será un valor "False". Por otro lado el método "endswith" realiza lo contrario que "startswith" y analiza si el "string" termina con un determinado patrón, devolviendo "True" en caso de encontrar la coincidencia y "False" en caso de que no. Ejemplo .. code-block:: python texto = "Hola Mundo" a = texto.startwith("Ho") print(a) a = texto.startwith("m") print(a) La salida del ejemplo anterior nos trae un True como valor de retorno, pues comienza con los caracteres 'Ho' y el segundo evidentemente trae un False. Reemplazo --------- La función "replace()" nos permite obtener una copia del "string" original y crear una nueva variable en la cual se aplicará un reemplazo de valores. Al igual que "find()" en la búsqueda, "replace()" recibe tres parámetros, de los cuales los dos primeros son obligatorios. El primero parámetro es la cadena que tiene que buscar y el segundo parámetro es el texto por el cual se va a reemplazar. Sintaxis .. code-block:: python texto.replace("valor a buscar", "valor para reemplazar") Ejemplo .. literalinclude:: ../examples/string/string10.py La salida espera al ejemplo anterior es: .. code-block:: text a la una, a las dos y a las tres a XXX una, a XXXs dos y a XXXs tres