Saltar al contenido principal

parseName

Paquete: @tiendana/utils

Parsea un nombre completo en español, separando nombre(s) y apellido(s), con manejo especial de preposiciones comunes (de, del, la, el).

Características​

✅ Separa nombre y apellidos
✅ Normaliza mayúsculas y espacios (' maría LÓPEZ ' → María López)
✅ Maneja preposiciones (de, del, la, el)
✅ Retorna componentes individuales
✅ Maneja nombres compuestos de hasta dos palabras
✅ Optimizado para nombres españoles

Firma​

function parseName(input: string): FullName

interface FullName {
name?: string;
lastName?: string;
firstLastName?: string;
secondLastName?: string;
joined?: string;
}

Parámetros​

ParámetroTipoDescripciónRequerido
inputstringNombre completo a parsear✅

Retorno​

Tipo: FullName

PropiedadTipoDescripción
namestring | undefinedNombre(s): una o dos palabras
firstLastNamestring | undefinedPrimer apellido (puede incluir preposición, p. ej. de la Cruz)
secondLastNamestring | undefinedSegundo apellido (en ejecución siempre es string; '' si no existe)
lastNamestring | undefinedfirstLastName y secondLastName separados por un espacio
joinedstring | undefinedNombre completo en un solo string (en ejecución siempre es string; ver el aviso de abajo)
joined repite el segundo apellido

Cuando existe segundo apellido, joined lo incluye dos veces, porque se construye como [name, lastName, secondLastName] unidos con espacios:

parseName('María López Pérez').joined;
// 'María López Pérez Pérez'

Con un solo apellido o con un solo término no hay duplicado de segundo apellido. Si necesitas el nombre completo sin repeticiones, arma ${name} ${lastName}. Con un solo término name y lastName son la misma palabra, así que usa solo name en ese caso.

Entrada vacía

Con '' solo se devuelven secondLastName: '' y joined: ''; name, lastName y firstLastName quedan undefined.

Ejemplos de Uso​

Nombre Simple​

import { parseName } from '@tiendana/utils';

parseName('Juan García');
// {
// name: 'Juan',
// lastName: 'García',
// firstLastName: 'García',
// secondLastName: '',
// joined: 'Juan García'
// }

Nombre con Dos Apellidos​

parseName('María López Pérez');
// {
// name: 'María',
// lastName: 'López Pérez',
// firstLastName: 'López',
// secondLastName: 'Pérez',
// joined: 'María López Pérez Pérez'
// }

Nombre Compuesto​

Con cuatro palabras o más, las dos primeras son el nombre.

parseName('José María García López');
// {
// name: 'José María',
// lastName: 'García López',
// firstLastName: 'García',
// secondLastName: 'López',
// joined: 'José María García López López'
// }

Con Preposición "de"​

parseName('Pedro de la Cruz');
// {
// name: 'Pedro',
// lastName: 'de la Cruz',
// firstLastName: 'de la Cruz',
// secondLastName: '',
// joined: 'Pedro de la Cruz'
// }

Con Preposición "del"​

parseName('Ana del Valle Ruiz');
// {
// name: 'Ana',
// lastName: 'del Valle Ruiz',
// firstLastName: 'del Valle',
// secondLastName: 'Ruiz',
// joined: 'Ana del Valle Ruiz Ruiz'
// }

Un Solo Término​

parseName('Ana');
// {
// name: 'Ana',
// lastName: 'Ana',
// firstLastName: 'Ana',
// secondLastName: '',
// joined: 'Ana Ana'
// }

Formularios de Registro​

interface RegistrationForm {
fullName: string;
email: string;
}

function processRegistration(form: RegistrationForm) {
const parsedName = parseName(form.fullName);

return {
email: form.email,
firstName: parsedName.name,
lastName: parsedName.lastName,
firstLastName: parsedName.firstLastName,
secondLastName: parsedName.secondLastName
};
}

processRegistration({
fullName: 'Carlos Andrés Martínez López',
email: 'carlos@example.com'
});
// {
// email: 'carlos@example.com',
// firstName: 'Carlos Andrés',
// lastName: 'Martínez López',
// firstLastName: 'Martínez',
// secondLastName: 'López'
// }

Generación de Username​

function generateUsername(fullName: string): string {
const { name = '', firstLastName = '' } = parseName(fullName);
const firstNamePart = name.split(' ')[0].toLowerCase();
const lastNamePart = firstLastName.replace(/\s+/g, '_').toLowerCase();

return `${firstNamePart}.${lastNamePart}`;
}

generateUsername('María José García López');
// 'maría.garcía' (aplica removeDiacritics si necesitas ASCII)

generateUsername('Pedro de la Cruz');
// 'pedro.de_la_cruz'

Display Name​

function formatDisplayName(fullName: string, format: 'short' | 'full' | 'formal'): string {
const parsed = parseName(fullName);

switch (format) {
case 'short':
return `${parsed.name} ${parsed.firstLastName}`;
case 'full':
return `${parsed.name} ${parsed.lastName}`;
case 'formal':
return `${parsed.firstLastName}, ${parsed.name}`;
default:
return fullName;
}
}

formatDisplayName('Juan Carlos García López', 'short');
// 'Juan Carlos García'

formatDisplayName('Juan Carlos García López', 'full');
// 'Juan Carlos García López'

formatDisplayName('Juan Carlos García López', 'formal');
// 'García, Juan Carlos'

Iniciales​

function getInitials(fullName: string): string {
const parsed = parseName(fullName);
const firstInitial = parsed.name?.charAt(0) ?? '';
const lastInitial = parsed.firstLastName?.charAt(0) ?? '';

return `${firstInitial}${lastInitial}`.toUpperCase();
}

getInitials('María López Pérez');
// 'ML'

getInitials('José María García López');
// 'JG'

Ordenamiento por Apellido​

interface Person {
fullName: string;
age: number;
}

function sortByLastName(people: Person[]): Person[] {
return [...people].sort((a, b) =>
(parseName(a.fullName).firstLastName ?? '')
.localeCompare(parseName(b.fullName).firstLastName ?? '')
);
}

Búsqueda por Apellido​

function searchByLastName(query: string, people: Person[]): Person[] {
const normalizedQuery = query.toLowerCase();

return people.filter(person => {
const parsed = parseName(person.fullName);
return (parsed.firstLastName ?? '').toLowerCase().includes(normalizedQuery) ||
(parsed.secondLastName ?? '').toLowerCase().includes(normalizedQuery);
});
}

Casos de Uso Comunes​

  • Formularios: Separar nombre y apellidos en campos individuales
  • Usernames: Generar usernames basados en nombre y apellido
  • Display names: Formatear nombres para mostrar
  • Iniciales: Generar iniciales para avatares
  • Ordenamiento y búsqueda: Por apellido
  • Exportación: Datos con campos separados

Lógica de Parsing​

  1. Elimina espacios sobrantes, pasa todo a minúsculas y pone en mayúscula la inicial de cada palabra, salvo de, del, la y el.
  2. Agrupa cada preposición con la palabra que la sigue (de la Cruz es un solo token).
  3. Con más de tres tokens, name son los dos primeros; si no, el primero.
  4. Con más de dos tokens, firstLastName es el penúltimo y secondLastName el último; si no, firstLastName es el último.
  5. lastName une ambos apellidos y joined une name, lastName y secondLastName.
parseName('Juan Carlos de la Cruz');
// name: 'Juan'
// firstLastName: 'Carlos'
// secondLastName: 'de la Cruz'

Notas Técnicas​

  • Preposiciones reconocidas: de, del, la, el
  • Mayúsculas y espacios: se normalizan
  • Nombres con un solo término: ese término se usa como nombre y también como firstLastName y lastName
  • Tokens: solo reconoce palabras con letras latinas; números y símbolos se descartan

Limitaciones​

Optimizado para nombres españoles

Esta función está optimizada para el formato de nombres españoles y latinoamericanos. Puede no funcionar correctamente con:

  • Nombres de otros idiomas con diferentes convenciones
  • Nombres con partículas nobiliarias complejas (von, van, zu, etc.)
  • Nombres con tres palabras donde la segunda sea parte del nombre
  • Nombres con caracteres especiales o números

Para nombres internacionales, considera usar librerías especializadas como humanparser o parse-full-name.

Asume el orden Nombre(s) Apellido(s)

Si el input es "García López Juan", el resultado es incorrecto:

parseName('García López Juan');
// name: 'García' ❌
// firstLastName: 'López'
// secondLastName: 'Juan'

Ver También​