Ir al contenido
angel.library

Strings y procesamiento de texto

Los strings son inmutables: cada método devuelve otro valor. length cuenta unidades UTF-16, no necesariamente caracteres visibles. Para búsquedas simples usa includes; para patrones, RegExp; para comparación humana, Intl.Collator; para grafemas, Intl.Segmenter.

Un string es una secuencia de texto inmutable. Ningún método modifica el valor original: cada transformación devuelve un string, un array, un número o un resultado nuevo. Puedes crearlo con comillas simples, dobles o template literals.

const name = "Mara"
const message = `Hola, ${name.toUpperCase()}`
message // 'Hola, MARA'
name // 'Mara': no cambió
Método o propiedadDevuelveMutaCaso de uso
lengthnúmero de unidades UTF-16novalidar longitud aproximada
at(index)carácter o undefinednoleer posiciones, incluidas negativas
charAt(index)carácter o ''nocompatibilidad con código antiguo
includes(text)booleanonosaber si contiene un fragmento
startsWith(text)booleanonocomprobar prefijos
endsWith(text)booleanonocomprobar extensiones o sufijos
indexOf(text)primera posición o -1nolocalizar una coincidencia
lastIndexOf(text)última posición o -1nolocalizar desde el final
search(regexp)posición o -1nobuscar con patrón
const file = "report.final.pdf"
file.length // 16
file.at(0) // 'r'
file.at(-1) // 'f'
file.includes("final") // true
file.startsWith("report") // true
file.endsWith(".pdf") // true
file.indexOf(".") // 6
file.lastIndexOf(".") // 12
file.search(/FINAL/i) // 7
MétodoDevuelveMutaNota
slice(start, end?)fragmento nuevonoacepta índices negativos
substring(start, end?)fragmento nuevonoconvierte negativos a cero
split(separator, limit?)arraynodivide el texto
concat(...values)string nuevonosuele ser más legible usar templates
repeat(count)string repetidonoseparadores o contenido repetido
const route = "/products/keyboard"
route.slice(1, 9) // 'products'
route.slice(-8) // 'keyboard'
route.substring(1, 9) // 'products'
route.split("/") // ['', 'products', 'keyboard']
"JS".repeat(3) // 'JSJSJS'
"Hola".concat(" ", "Ana") // 'Hola Ana'

Para construir texto con variables, los template literals suelen comunicar mejor la intención:

const product = "Monitor"
const price = 350
const summary = `${product}: $${price}`
summary // 'Monitor: $350'
MétodoResultadoMutaCaso de uso
trim()elimina espacios en ambos extremosnolimpiar formularios
trimStart()elimina espacios inicialesnoentradas alineadas
trimEnd()elimina espacios finalesnolíneas de archivos
toLowerCase()texto en minúsculasnocomparación simple
toUpperCase()texto en mayúsculasnopresentación o códigos
normalize(form?)forma Unicode normalizadanocomparar texto equivalente
padStart(length, fill?)relleno al inicionoids y horas
padEnd(length, fill?)relleno al finalnocolumnas de texto
const raw = " JavaScript "
raw.trim() // 'JavaScript'
raw.trimStart() // 'JavaScript '
raw.toLowerCase() // ' javascript '
"7".padStart(3, "0") // '007'
"9".padEnd(3, ".") // '9..'
const composed = "é"
const decomposed = "e\u0301"
composed === decomposed // false
composed.normalize() === decomposed.normalize() // true

Las variantes locales reciben reglas del idioma cuando el caso depende de la región:

"istanbul".toLocaleUpperCase("tr") // 'İSTANBUL'
"I".toLocaleLowerCase("tr") // 'ı'

No uses minúsculas como sustituto universal de una comparación lingüística; Intl.Collator permite declarar sensibilidad, puntuación y orden.

MétodoDevuelveMutaDiferencia
replace(search, value)string nuevonoreemplaza la primera coincidencia; con regex global, todas
replaceAll(search, value)string nuevonoreemplaza todas las coincidencias de texto
match(regexp)array, coincidencia o nullnoextrae coincidencias
matchAll(regexp)iterador de coincidenciasnoconserva grupos e índices de todas
const sentence = "rojo, rojo y azul"
sentence.replace("rojo", "verde")
// 'verde, rojo y azul'
sentence.replaceAll("rojo", "verde")
// 'verde, verde y azul'
"Pedido AB-123".match(/[A-Z]{2}-\d{3}/)?.[0]
// 'AB-123'

replace puede recibir una función. Resulta útil cuando el valor depende de cada coincidencia:

const text = "subtotal 40, impuesto 8"
const doubled = text.replace(/\d+/g, (value) => String(Number(value) * 2))
doubled // 'subtotal 80, impuesto 16'
const input = "2026-08-18"
const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = input.match(pattern)
result?.groups
// { year: '2026', month: '08', day: '18' }

localeCompare compara según un locale. Para ordenar muchas cadenas, crea un Intl.Collator una sola vez.

const names = ["Ángel", "ana", "Carlos"]
const collator = new Intl.Collator("es", { sensitivity: "base" })
names.toSorted(collator.compare)
// ['ana', 'Ángel', 'Carlos']

El resultado exacto de una comparación es negativo, cero o positivo; no asumas que siempre será -1 o 1.

length cuenta unidades UTF-16, no siempre caracteres percibidos por una persona. El spread y Array.from manejan puntos de código, aunque emojis compuestos pueden seguir ocupando varios elementos.

"😀".length // 2
;[..."😀"].length // 1
"👨‍👩‍👧‍👦".length // 11
;[..."👨‍👩‍👧‍👦"].length // 7: es un único grafema visual

Para límites de palabras, frases o grafemas usa Intl.Segmenter cuando esté disponible en los runtimes objetivo.

const segmenter = new Intl.Segmenter("es", { granularity: "grapheme" })
const graphemes = [...segmenter.segment("A👨‍👩‍👧‍👦B")].map((item) => item.segment)
graphemes // ['A', '👨‍👩‍👧‍👦', 'B']
APIDevuelveUso
codePointAt(index)punto de código o undefinedinspeccionar Unicode completo
charCodeAt(index)unidad UTF-16 o NaNtrabajar con formatos UTF-16
String.fromCodePoint(...codes)stringcrear texto desde puntos de código
String.fromCharCode(...units)stringcrear desde unidades UTF-16
String.rawstring sin procesar escapes del templaterutas, patrones o debugging
"😀".codePointAt(0) // 128512
"😀".charCodeAt(0) // 55357: solo la primera unidad
String.fromCodePoint(128512) // '😀'
String.raw`linea\n siguiente` // 'linea\\n siguiente'

Un string puede contener un surrogate aislado que no representa un punto de código Unicode válido. APIs modernas permiten detectarlo o reemplazarlo por U+FFFD.

const malformed = "\uD800"
malformed.isWellFormed() // false
malformed.toWellFormed() // '�'
"Hola 😀".isWellFormed() // true

Esto importa antes de codificar texto para URLs, archivos o sistemas que exigen Unicode bien formado. Comprueba compatibilidad si los runtimes soportados son antiguos.

function toSlug(value) {
return value
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.toLowerCase()
.trim()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-|-$/g, "")
}
toSlug(" Guía de JavaScript moderno ")
// 'guia-de-javascript-moderno'

Este slug es práctico para texto latino básico. En un producto internacional, define una política para otros alfabetos y evita asumir que toda URL debe transliterarse de la misma forma.