[ Web Proxy ]
URL:
Viewing: https://es.javascript.info/string [Back]  [Original]

Strings
ES

Queremos que este proyecto de cdigo abierto est disponible para personas de todo el mundo.

Ayuda a traducir el contenido de este tutorial a tu idioma!

    Buscar en Javascript.info:
    Buscar en el tutorial:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Strings

    En JavaScript, los datos textuales son almacenados como strings (cadena de caracteres). No hay un tipo de datos separado para caracteres unitarios.

    El formato interno para strings es siempre UTF-16, no est vinculado a la codificacin de la pgina.

    Comillas

    Recordemos los tipos de comillas.

    Los strings pueden estar entre comillas simples, comillas dobles o backticks (acento grave):

    let single = 'comillas simples';
    let double = "comillas dobles";
    
    let backticks = `backticks`;

    Comillas simples y dobles son esencialmente lo mismo. En cambio, los backticks nos permiten adems ingresar expresiones dentro del string envolvindolos en ${}:

    function sum(a, b) {
      return a + b;
    }
    
    alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.

    Otra ventaja de usar backticks es que nos permiten extender en mltiples lneas el string:

    let guestList = `Invitados:
     * Juan
     * Pedro
     * Maria
    `;
    
    alert(guestList); // una lista de invitados, en mltiples lneas

    Se ve natural, no es cierto? Pero las comillas simples y dobles no funcionan de esa manera.

    Si intentamos usar comillas simples o dobles de la misma forma, obtendremos un error:

    let guestList = "Invitados:  // Error: Unexpected token ILLEGAL
      * Juan";

    Las comillas simples y dobles provienen de la creacin de lenguajes en tiempos ancestrales, cuando la necesidad de mltiples lneas no era tomada en cuenta. Los backticks aparecieron mucho despus y por ende son ms verstiles.

    Los backticks adems nos permiten especificar una funcin de plantilla antes del primer backtick. La sintaxis es: func`string`. La funcin func es llamada automticamente, recibe el string y la expresin insertada, y los puede procesar. Eso se llama plantillas etiquetadas. Es raro verlo implementado, pero puedes leer ms sobre esto en el manual.

    Caracteres especiales

    Es posible crear strings de mltiples lneas usando comillas simples, usando un llamado carcter de nueva lnea, escrito como \n, lo que denota un salto de lnea:

    let guestList = 'Invitados:\n * Juan\n * Pedro\n * Maria';
    
    alert(guestList); // lista de invitados en mltiples lneas, igual a la de ms arriba

    Como ejemplo ms simple, estas dos lneas son iguales, pero escritas en forma diferente:

    let str1 = "Hello\nWorld"; // dos lneas usando el "smbolo de nueva lnea"
    
    // dos lneas usando nueva lnea normal y backticks
    let str2 = `Hello
    World`;
    
    alert(str1 == str2); // true

    Existen otros caracteres especiales, menos comunes.

    Carcter Descripcin
    \n Nueva lnea
    \r En Windows, los archivos de texto usan una combinacin de dos caracteres \r\n para representar un corte de lnea, mientras que en otros SO es simplemente \n. Esto es por razones histricas, la mayora del software para Windows tambin reconoce \n.
    \',\",\` Comillas
    \\ Barra invertida
    \t Tabulacin
    \b, \f, \v Retroceso, avance de formulario, tabulacin vertical Se mencionan para ser exhaustivos. Vienen de muy viejos tiempos y no se usan actualmente (puedes olvidarlos ya).

    Como puedes ver, todos los caracteres especiales empiezan con la barra invertida \. Se lo llama carcter de escape.

    Y como es tan especial, si necesitamos mostrar el verdadero carcter \ dentro de un string, necesitamos duplicarlo:

    alert( `La barra invertida: \\` ); // La barra invertida: \

    Las llamadas comillas escapadas \', \", \` se usan para insertar una comilla en un string entrecomillado con el mismo tipo de comilla.

    Por ejemplo:

    alert('Yo soy la \'morsa\'!'); // Yo soy la 'morsa'!

    Como puedes ver, debimos anteponer un carcter de escape \ antes de cada comilla ya que de otra manera hubiera indicado el final del string.

    Obviamente, solo necesitan ser escapadas las comillas que son iguales a las que estn rodeando al string. Una solucin ms elegante es cambiar a comillas dobles o backticks:

    alert("Yo soy la 'morsa'!"); // Yo soy la 'morsa'!

    Adems de estos caracteres especiales, tambin hay una notacin especial para cdigos Unicode \u que se usa raramente. Los cubrimos en el captulo opcional acerca de Unicode.

    Largo del string

    La propiedad length contiene el largo del string:

    alert(`Mi\n`.length); // 3

    Nota que \n es un solo carcter, por lo que el largo total es 3.

    length es una propiedad

    Quienes tienen experiencia en otros lenguajes pueden cometer el error de escribir str.length() en vez de str.length. Eso no funciona.

    Nota que str.length es una propiedad numrica, no una funcin. No hay que agregar parntesis despus de ella. No es .length(), sino .length.

    Accediendo caracteres

    Para acceder a un carcter en la posicin pos, se debe usar corchetes, [pos], o llamar al mtodo str.at(pos). El primer carcter comienza desde la posicin cero:

    let str = `Hola`;
    
    // el primer carcter
    alert( str[0] ); // H
    alert( str.at(0) ); // H
    
    // el ltimo carcter
    alert( str[str.length - 1] ); // a
    alert( str.at(-1) );

    Como puedes ver, el mtodo .at(pos) tiene el beneficio de permitir una posicin negativa. Si pos es negativa, se cuenta desde el final del string.

    As, .at(-1) significa el ltimo carcter, y .at(-2) es el anterior a l, etc.

    Los corchetes siempre devuelven undefined para ndices negativos:

    let str = `Hola`;
    
    alert( str[-2] ); // undefined
    alert( str.at(-2) ); // l

    Podemos adems iterar sobre los caracteres usando for..of:

    for (let char of 'Hola') {
      alert(char); // H,o,l,a (char se convierte en "H", luego "o", luego "l", etc.)
    }

    Los strings son inmutables

    Los strings no pueden ser modificados en JavaScript. Es imposible modificar un carcter.

    Intentmoslo para demostrar que no funciona:

    let str = 'Hola';
    
    str[0] = 'h'; // error
    alert(str[0]); // no funciona

    Lo usual para resolverlo es crear un nuevo string y asignarlo a str reemplazando el string completo.

    Por ejemplo:

    let str = 'Hola';
    
    str = 'h' + str[1] + str[2] + str[3]; // reemplaza el string
    
    alert( str ); // hola

    En las secciones siguientes veremos ms ejemplos de esto.

    Cambiando capitalizacin

    Los mtodos toLowerCase() y toUpperCase() cambian los caracteres a minscula y mayscula respectivamente:

    alert('Interfaz'.toUpperCase()); // INTERFAZ
    alert('Interfaz'.toLowerCase()); // interfaz

    Si queremos un solo carcter en minscula:

    alert('Interfaz'[0].toLowerCase()); // 'i'

    Buscando una subcadena de caracteres

    Existen muchas formas de buscar por subcadenas de caracteres dentro de una cadena completa.

    str.indexOf

    El primer mtodo es str.indexOf(substr, pos).

    Este busca un substr en str, comenzando desde la posicin entregada pos, y retorna la posicin donde es encontrada la coincidencia o -1 en caso de no encontrar nada.

    Por ejemplo:

    let str = 'Widget con id';
    
    alert(str.indexOf('Widget')); // 0, ya que 'Widget' es encontrado al comienzo
    alert(str.indexOf('widget')); // -1, no es encontrado, la bsqueda toma en cuenta minsculas y maysculas.
    
    alert(str.indexOf('id')); // 1, "id" es encontrado en la posicin 1 (..idget con id)

    El segundo parmetro es opcional y nos permite buscar desde la posicin entregada.

    Por ejemplo, la primera ocurrencia de "id" es en la posicin 1. Para buscar por la siguiente ocurrencia, comencemos a buscar desde la posicin 2:

    let str = 'Widget con id';
    
    alert(str.indexOf('id', 2)); // 11

    Si estamos interesados en todas las ocurrencias, podemos correr indexOf en un bucle. Cada nuevo llamado es hecho utilizando la posicin posterior a la encontrada anteriormente:

    let str = 'Astuto como un zorro, fuerte como un buey';
    
    let target = 'como'; // busquemos por l
    
    let pos = 0;
    while (true) {
      let foundPos = str.indexOf(target, pos);
      if (foundPos == -1) break;
    
      alert(`Encontrado en ${foundPos}`);
      pos = foundPos + 1; // continuar la bsqueda desde la siguiente posicin
    }

    Podemos escribir el mismo algoritmo, pero ms corto:

    let str = 'Astuto como un zorro, fuerte como un buey';
    let target = "como";
    
    let pos = -1;
    while ((pos = str.indexOf(target, pos + 1)) != -1) {
      alert( pos );
    }
    str.lastIndexOf(substr, position)

    Tambin hay un mtodo similar str.lastIndexOf(substr, position) que busca desde el final del string hasta el comienzo.

    Este imprimir las ocurrencias en orden invertido.

    Existe un leve inconveniente con indexOf en la prueba if. No podemos utilizarlo en el if como sigue:

    let str = "Widget con id";
    
    if (str.indexOf("Widget")) {
        alert("Lo encontramos"); // no funciona!
    }

    La alerta en el ejemplo anterior no se muestra ya que str.indexOf("Widget") retorna 0 (lo que significa que encontr el string en la posicin inicial). Eos correcto, pero if considera 0 como falso.

    Por ello debemos preguntar por -1:

    let str = "Widget con id";
    
    if (str.indexOf("Widget") != -1) {
        alert("Lo encontramos"); // ahora funciona!
    }

    includes, startsWith, endsWith

    El mtodo ms moderno str.includes(substr, pos) devuelve true o false si str contiene substr o no.

    Es la opcin adecuada si lo que necesitamos es verificar que exista, pero no su posicin.

    alert('Widget con id'.includes('Widget')); // true
    
    alert('Hola'.includes('Adis')); // false

    El segundo argumento opcional de str.includes es la posicin desde donde comienza a buscar:

    alert('Midget'.includes('id')); // true
    alert('Midget'.includes('id', 3)); // false, desde la posicin 3 no hay "id"

    Los mtodos str.startsWith (comienza con) y str.endsWith (termina con) hacen exactamente lo que dicen:

    alert( "Widget".startsWith("Wid") ); // true, "Widget" comienza con "Wid"
    alert( "Widget".endsWith("get") ); // true, "Widget" termina con "get"

    Obteniendo un substring

    Existen 3 mtodos en JavaScript para obtener un substring: substring, substr y slice.

    str.slice(comienzo [, final])

    Retorna la parte del string desde comienzo hasta (pero sin incluir) final.

    Por ejemplo:

    let str = "stringify";
    alert( str.slice(0, 5) ); // 'strin', el substring desde 0 hasta 5 (sin incluir 5)
    alert( str.slice(0, 1) ); // 's', desde 0 hasta 1, pero sin incluir 1, por lo que slo el carcter en 0

    Si no existe el segundo argumento, entonces slice va hasta el final del string:

    let str = "stringify";
    alert( str.slice(2) ); // ringify, desde la 2nda posicin hasta el final

    Tambin son posibles valores negativos para comienzo/final. Estos indican que la posicin es contada desde el final del string.

    let str = "stringify";
    // comienza en la 4ta posicin desde la derecha, finaliza en la 1era posicin desde la derecha
    alert( str.slice(-4, -1) ); // 'gif'
    str.substring(comienzo [, final])

    Devuelve la parte del string entre comienzo y final (no incluyendo final).

    Esto es casi lo mismo que slice, pero permite que comienzo sea mayor que final (en este caso solo intercambia los valores de comienzo y final).

    Por ejemplo:

    let str = "stringify";
    
    // esto es lo mismo para substring
    alert( str.substring(2, 6) ); // "ring"
    alert( str.substring(6, 2) ); // "ring"
    
    // ...pero no para slice:
    alert( str.slice(2, 6) ); // "ring" (lo mismo)
    alert( str.slice(6, 2) ); // "" (un string vaco)

    Los argumentos negativos (al contrario de slice) no son soportados, son tratados como 0.

    str.substr(comienzo [, largo])

    Retorna la parte del string desde comienzo, con el largo dado.

    A diferencia de los mtodos anteriores, este nos permite especificar el largo en lugar de la posicin final:

    let str = "stringify";
    alert( str.substr(2, 4) ); // ring, desde la 2nda posicin toma 4 caracteres

    El primer argumento puede ser negativo, para contar desde el final:

    let str = "stringify";
    alert( str.substr(-4, 2) ); // gi, desde la 4ta posicin toma 2 caracteres

    Este mtodo reside en el Anexo B de la especificacin del lenguaje. Esto significa que solo necesitan darle soporte los motores Javascript de los navegadores, y no es recomendable su uso. Pero en la prctica, es soportado en todos lados.

    Recapitulemos los mtodos para evitar confusiones:

    mtodo selecciona negativos
    slice(comienzo, final) desde comienzo hasta final (sin incluir final) permite negativos
    substring(comienzo, final) entre comienzo y final (no incluye final) valores negativos significan 0
    substr(comienzo, largo) desde comienzo toma largo caracteres permite negativos comienzo
    Cul elegir?

    Todos son capaces de hacer el trabajo. Formalmente, substr tiene una pequea desventaja: no es descrito en la especificacin central de JavaScript, sino en el anexo B, el cual cubre caractersticas slo de navegadores, que existen principalmente por razones histricas. Por lo que entornos sin navegador pueden fallar en compatibilidad. Pero en la prctica, funciona en todos lados.

    De las otras dos variantes, slice es algo ms flexible, permite argumentos negativos y es ms corta.

    Entones, es suficiente recordar nicamente slice.

    Comparando strings

    Como aprendimos en el captulo Comparaciones, los strings son comparados carcter por carcter en orden alfabtico.

    Aunque existen algunas singularidades.

    1. Una letra minscula es siempre mayor que una mayscula:

      alert('a' > 'Z'); // true
    2. Las letras con marcas diacrticas estn fuera de orden:

      alert('sterreich' > 'Zealand'); // true

      Esto puede conducir a resultados extraos si ordenamos los nombres de estos pases. Usualmente, se esperara que Zealand apareciera despus de sterreich en la lista.

    Para entender lo que pasa, debemos tener en cuenta que los strings en JavaScript son codificados usando UTF-16. Esto significa: cada carcter tiene un cdigo numrico correspondiente.

    Existen mtodos especiales que permiten obtener el carcter para el cdigo y viceversa.

    str.codePointAt(pos)

    Devuelve un nmero decimal que representa el cdigo de carcter en la posicin pos:

    // maysculas y minsculas tienen cdigos diferentes
    alert( "Z".codePointAt(0) ); // 90
    alert( "z".codePointAt(0) ); // 122
    alert( "z".codePointAt(0).toString(16) ); // 7a (si necesitamos el valor del cdigo en hexadecimal)
    String.fromCodePoint(code)

    Crea un carcter por su cdigo numrico:

    alert( String.fromCodePoint(90) ); // Z
    alert( String.fromCodePoint(0x5a) ); // Z (tambin podemos usar un valor hexa como argumento)

    Ahora veamos los caracteres con cdigos 65..220 (el alfabeto latino y algo ms) transformndolos a string:

    let str = '';
    
    for (let i = 65; i <= 220; i++) {
      str += String.fromCodePoint(i);
    }
    alert( str );
    // salida:
    // ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
    // 

    Lo ves? Caracteres en maysculas van primero, luego unos cuantos caracteres especiales, luego las minsculas.

    Ahora se vuelve obvio por qu a > Z.

    Los caracteres son comparados por su cdigo numrico. Cdigo mayor significa que el carcter es mayor. El cdigo para a (97) es mayor que el cdigo para Z (90).

    • Todas las letras minsculas van despus de las maysculas ya que sus cdigos son mayores.
    • Algunas letras como se mantienen apartadas del alfabeto principal. Aqu el cdigo es mayor que cualquiera desde a hasta z.

    Comparaciones correctas

    El algoritmo correcto para realizar comparaciones de strings es ms complejo de lo que parece, debido a que los alfabetos son diferentes para diferentes lenguajes. Una letra que se ve igual en dos alfabetos distintos, pueden tener distintas posiciones.

    Por lo que el navegador necesita saber el lenguaje para comparar.

    Por suerte, todos los navegadores modernos mantienen la internacionalizacin del estndar ECMA 402.

    Este provee un mtodo especial para comparar strings en distintos lenguajes, siguiendo sus reglas.

    El llamado a str.localeCompare(str2) devuelve un entero indicando si str es menor, igual o mayor que str2 de acuerdo a las reglas del lenguaje:

    • Retorna 1 si str es mayor que str2.
    • Retorna -1 si str es menor que str2.
    • Retorna 0 si son equivalentes.

    Por ejemplo:

    alert('sterreich'.localeCompare('Zealand')); // -1

    Este mtodo tiene dos argumentos adicionales especificados en la documentacin, la cual le permite especificar el lenguaje (por defecto lo toma del entorno) y configura reglas adicionales como sensibilidad a las maysculas y minsculas, o si "a" y "a" deben ser tratadas como iguales, etc.

    Resumen

    • Existen 3 tipos de entrecomillado. Los backticks permiten que una cadena abarque varias lneas e insertar expresiones ${}.
    • Podemos usar caracteres especiales como el salto de lnea \n.
    • Para obtener un carcter, usa: [] o el mtodo at.
    • Para obtener un substring, usa: slice o substring.
    • Para convertir un string en minsculas/maysculas, usa: toLowerCase/toUpperCase.
    • Para buscar un substring, usa: indexOf, o para chequeos simples includes/startsWith/endsWith.
    • Para comparar strings de acuerdo al idioma, usa: localeCompare, de otra manera sern comparados por sus cdigos de carcter.

    Existen otros mtodos tiles:

    • str.trim() remueve (recorta) espacios desde el comienzo y final de un string.
    • str.repeat(n) repite el string n veces.
    • y ms. Puedes ver el manual para ms detalles.

    Los strings tambin tienen mtodos para buscar/reemplazar que usan expresiones regulares. Este es un tema muy amplio, por ello es explicado en una seccin separada del tutorial Expresiones Regulares.

    Adems, es importante saber que los strings estn basados en la codificacin Unicode, y se presentan algunas complicaciones en las comparaciones de string. Hay ms acerca de Unicode en el captulo Unicode, String internals.

    Tareas

    importancia: 5

    Escribe una funcin ucFirst(str) que devuelva el string str con el primer carcter en mayscula, por ejemplo:

    ucFirst("john") == "John";

    Abrir en entorno controlado con pruebas.

    solucin

    No podemos reemplazar el primer carcter, debido a que los strings en JavaScript son inmutables.

    Pero podemos hacer un nuevo string basado en el existente, con el primer carcter en maysculas:

    let newStr = str[0].toUpperCase() + str.slice(1);

    Sin embargo, hay un pequeo problema. Si str est vaco, entonces str[0] es undefined, y como undefined no tiene el mtodo toUpperCase(), obtendremos un error.

    Lo ms fcil es agregar una verificacin de cadena vaca:

    function ucFirst(str) {
      if (!str) return str;
    
      return str[0].toUpperCase() + str.slice(1);
    }
    
    alert( ucFirst("john") ); // John

    Abrir la solucin con pruebas en un entorno controlado.

    importancia: 5

    Escribe una funcin checkSpam(str) que devuelva true si str contiene viagra o XXX, de lo contrario false.

    La funcin debe ser insensible a maysculas y minsculas:

    checkSpam('compra ViAgRA ahora') == true
    checkSpam('xxxxx gratis') == true
    checkSpam("coneja inocente") == false

    Abrir en entorno controlado con pruebas.

    solucin

    Para que la bsqueda no distinga entre maysculas y minsculas, llevemos el string a minsculas y luego busquemos:

    function checkSpam(str) {
      let lowerStr = str.toLowerCase();
    
      return lowerStr.includes('viagra') || lowerStr.includes('xxx');
    }
    
    alert( checkSpam('compra ViAgRA ahora') );
    alert( checkSpam('xxxxx gratis') );
    alert( checkSpam("coneja inocente") );

    Abrir la solucin con pruebas en un entorno controlado.

    importancia: 5

    Crea una funcin truncate(str, maxlength) que verifique la longitud de str y, si excede maxlength reemplaza el final de str con el carcter de puntos suspensivos "", para hacer su longitud igual a maxlength.

    El resultado de la funcin debe ser la cadena truncada (si es necesario).

    Por ejemplo:

    truncate("Lo que me gustara contar sobre este tema es:", 20) = "Lo que me gustara c"
    
    truncate("Hola a todos!", 20) = "Hola a todos!"

    Abrir en entorno controlado con pruebas.

    solucin

    La longitud mxima debe ser maxlength, por lo que debemos acortarla un poco para dar espacio a los puntos suspensivos.

    Tener en cuenta que en realidad hay un nico carcter unicode para puntos suspensivos. Eso no son tres puntos.

    function truncate(str, maxlength) {
      return (str.length > maxlength) ?
        str.slice(0, maxlength - 1) + '' : str;
    }

    Abrir la solucin con pruebas en un entorno controlado.

    importancia: 4

    Tenemos un costo en forma de $120. Es decir: el signo de dlar va primero y luego el nmero.

    Crea una funcin extractCurrencyValue(str) que extraiga el valor numrico de dicho string y lo devuelva.

    Por ejemplo:

    alert( extractCurrencyValue('$120') === 120 ); // true

    Abrir en entorno controlado con pruebas.

    solucin
    function extractCurrencyValue(str) {
      return +str.slice(1);
    }

    Abrir la solucin con pruebas en un entorno controlado.

    Mapa del Tutorial

    Comentarios

    lea esto antes de comentar
    • Si tiene sugerencias sobre qu mejorar, por favor enviar una propuesta de GitHub o una solicitud de extraccin en lugar de comentar.
    • Si no puede entender algo en el artculo, por favor explique.
    • Para insertar algunas palabras de cdigo, use la etiqueta <code>, para varias lneas envolverlas en la etiqueta <pre>, para ms de 10 lneas utilice una entorno controlado (sandbox) (plnkr, jsbin, codepen)

    Web Proxy Viewer  |  New URL  |  Original Page