-
-
Save eduardoromero/8495437 to your computer and use it in GitHub Desktop.
<?php | |
/* separar el nombre completo en espacios */ | |
$tokens = explode(' ', trim($full_name)); | |
/* arreglo donde se guardan las "palabras" del nombre */ | |
$names = array(); | |
/* palabras de apellidos (y nombres) compuetos */ | |
$special_tokens = array('da', 'de', 'del', 'la', 'las', 'los', 'mac', 'mc', 'van', 'von', 'y', 'i', 'san', 'santa'); | |
$prev = ""; | |
foreach($tokens as $token) { | |
$_token = strtolower($token); | |
if(in_array($_token, $special_tokens)) { | |
$prev .= "$token "; | |
} else { | |
$names[] = $prev. $token; | |
$prev = ""; | |
} | |
} | |
$num_nombres = count($names); | |
$nombres = $apellidos = ""; | |
switch ($num_nombres) { | |
case 0: | |
$nombres = ''; | |
break; | |
case 1: | |
$nombres = $names[0]; | |
break; | |
case 2: | |
$nombres = $names[0]; | |
$apellidos = $names[1]; | |
break; | |
case 3: | |
$apellidos = $names[0] . ' ' . $names[1]; | |
$nombres = $names[2]; | |
default: | |
$apellidos = $names[0] . ' '. $names[1]; | |
unset($names[0]); | |
unset($names[1]); | |
$nombres = implode(' ', $names); | |
break; | |
} | |
$nombres = mb_convert_case($nombres, MB_CASE_TITLE, 'UTF-8'); | |
$apellidos = mb_convert_case($apellidos, MB_CASE_TITLE, 'UTF-8'); |
A mí me funcionó mejor modificando esto:
case 3:
$nombres = $names[0] . ' ' . $names[1];
$apellidos = $names[2];
default:
$nombres = $names[0] . ' ' . $names[1];
unset($names[0]);
unset($names[1]);
$apellidos = implode(' ', $names);
break;
Gracias!!!! :) por la aportación
¡Gracias!
Excelente aporte!
👏 👏
Por qué en el "case 3" y "default" pones los apellidos en los índices 0 y 1? Traduje ese código a .NET y en efecto, funciona bien cambiando los índices en ambos case.
Todavia tienes a la mano ese código en .NET?
Excelente aporte y ya listo para usar, Gracias !!!
Dejo alguna mejora extra:
case 3:
$nombres = $names[0];
$apellidos = $names[1]. ' ' . $names[2];
case 4:
$nombres = $names[0]. ' ' . $names[1];
$apellidos = $names[2]. ' ' . $names[3];
break;
default:
$nombres = $names[0] . ' ' . $names[1];
unset($names[0]);
unset($names[1]);
$apellidos = implode(' ', $names);
break;
Gracias Gente! esto es muy bueno.
excelente aporte, mesirvio... lo pase a punto net y le hice unas pequeñas mejoras.
/* separar el nombre completo en espacios /
string nombreCompleto = "CERVANTES GONZALEZ JONATHAN SANTIAGO";
char []separador = {' '};
/ separar el nombre completo en espacios */
/* arreglo donde se guardan las "palabras" del nombre */
string []tokens=nombreCompleto.Trim().Split(separador);
/* palabras de apellidos (y nombres) compuetos */
string []tokensEspeciales ={"da", "de", "del", "la", "las", "los", "mac", "mc", "van", "von", "y", "i", "san", "santa"};
string prev = "";
List<string> nombresLista =new List<string>();
foreach (var item in tokens)
{
if(item!="")
{
string actual=item.ToLower();
if(tokensEspeciales.Contains(actual))
{
prev = prev+actual.ToUpper() + " ";
}else{
nombresLista.Add(prev + item.ToUpper());
prev="";
}
}
}
int num_nombres = nombresLista.Count();
string nombres ="";
string primerApellido = "";
string segundoApellido = "";
switch (num_nombres) {
case 0:
nombres = "";
break;
case 1:
nombres = nombresLista[0];
break;
case 2:
primerApellido = nombresLista[0];
nombres = nombresLista[1];
break;
case 3:
primerApellido = nombresLista[0];
segundoApellido= nombresLista[1];
nombres = nombresLista[2];
break;
case 4:
primerApellido = nombresLista[0];
segundoApellido= nombresLista[1];
nombres = nombresLista[2]+" "+nombresLista[3];
break;
default:
primerApellido = nombresLista[0];
segundoApellido= nombresLista[1];
nombresLista.RemoveAt(0);
nombresLista.RemoveAt(0);
nombres = String.Join(" ", nombresLista);
break;
}
Console.WriteLine("primerApellido"+ primerApellido);
Console.WriteLine("segundoApellido" + segundoApellido);
Console.WriteLine("nombres" + nombres);
Console.ReadKey();
¡Muchas gracias, me ayudó mucho tu aporte!
Dejo el código en JavaScript 👾:
name1 = "ANDRÉ ALMANZA HERRERA";
function main(){
getNameAndLastName(name1);
}
function getNameAndLastName(str) {
var tokens = str.split(' ');
// Arreglo donde se guardan las palabras del nombre.
var names = new Array();
// Palabras de apellidos y nombres compuestos
const special_tokens = new Array('da','de','del','la', 'las','los','mac','mc','van','von','y','i','san','santa');
var prev = "";
tokens.forEach(token =>{
var _token = token.toLowerCase();
if(special_tokens.includes(_token)){
prev = `${prev}${firstLetterUpperCase(_token)} `;
}else{
names.push(`${prev}${firstLetterUpperCase(_token)}`);
prev = "";
}
});
var num_nombres = names.length;
var nombres = "",
apellidos = "";
switch (num_nombres){
case 0:
nombres = '';
break;
case 1:
nombres = names[0];
break;
case 2:
nombres = names[0];
apellidos = names[1];
break;
case 3:
nombres = names[0];
apellidos = `${names[1]} ${names[2]}`;
break;
case 4:
nombres = `${names[0]} ${names[1]}`;
apellidos = `${names[2]} ${names[3]}`;
break;
default:
nombres = `${names[0]} ${names[1]}`;
names.splice(0,2);
apellidos = names.join(" ");
break;
}
console.log(`Nombres: ${nombres}`);
console.log(`Apellidos: ${apellidos}`);
}
/* Funciones auxiliares */
function firstLetterUpperCase(str){
return str.charAt(0).toUpperCase() + str.slice(1);
}
Dejo el código en Dart para Flutter.
sepApellidoprin(String name1) {
getNameAndLastName(name1);
}
getNameAndLastName(str) {
var tokens = str.split(' ');
// Arreglo donde se guardan las palabras del nombre.
var names = new List<String>.empty(growable: true);
// Palabras de apellidos y nombres compuestos
const special_tokens = [
'da',
'de',
'del',
'la',
'las',
'los',
'mac',
'mc',
'van',
'von',
'y',
'i',
'san',
'santa'
];
var prev = "";
tokens.forEach((token) {
var _token = token.toLowerCase();
if (special_tokens.contains(_token)) {
prev = "${prev}${firstLetterUpperCase(_token)}";
} else {
names.add("${prev}${firstLetterUpperCase(_token)}");
prev = "";
}
});
var num_nombres = names.length;
var nombres = "", apellidos = "";
switch (num_nombres) {
case 0:
nombres = '';
break;
case 1:
nombres = names[0];
break;
case 2:
nombres = names[0];
apellidos = names[1];
break;
case 3:
nombres = names[0];
apellidos = "${names[1]} ${names[2]}";
break;
case 4:
nombres = "${names[0]} ${names[1]}";
apellidos = "${names[2]} ${names[3]}";
break;
default:
nombres = "${names[0]} ${names[1]}";
names.sublist(0, 2);
apellidos = names.join(" ");
break;
}
print("Nombres: ${nombres}");
print("Apellidos:${apellidos}");
}
/* Funciones auxiliares */
firstLetterUpperCase(str) {
return str[0].toUpperCase() + str.substring(1);
}
Muchas gracias Eduardo, adjunto la version como función en Python
def namesplit(name):
# Para convertir los Nombres y Apellidos
# Parametro esperado con nombre primero y apellidos despues
# Use https://gist.github.com/eduardoromero/8495437
tokens = name.split()
names = []
# Apellidos compuestos
special_tokens = ['da', 'de', 'del', 'la', 'las', 'los', 'mac', 'mc', 'van', 'von', 'y', 'i', 'san', 'santa']
prev=""
for token in tokens:
if token.lower() in special_tokens:
prev += token + " "
else:
names.append(prev+token)
prev=""
num_nombres = len(names)
nombres, apellidos = ("","")
if num_nombres == 0:
return nombres, apellidos
elif num_nombres == 1:
nombres = names[0]
return nombres, apellidos
elif num_nombres == 2:
nombres = names[0]
apellidos = names[1]
return nombres, apellidos
elif num_nombres == 3:
nombres = names[0]
apellidos = names[1] + " " + names[2]
return nombres, apellidos
else:
apellidos = names[num_nombres-2] + " " + names[num_nombres-1]
names.pop()
names.pop()
nombres = " ".join(names)
return nombres, apellidos
Muchas gracias por el aporte, hice una pequeña modificación en php (laravel) para el escenario donde se desea obtener el apellido paterno, apellido materno, primer nombre y segundo nombre por si alguien le interesa usándolo en un helpers y devolviendo en objeto.
// app/Helpers/FuncionesGenerales.php
function splitFullNameToIndividual($full_name)
{
/* Convierto a mayascula */
$full_name = Str::upper($full_name);
/* separar el nombre completo en espacios */
$tokens = Str::of($full_name)->trim()->explode(' ');
/* arreglo donde se guardan las "palabras" del nombre */
$names = array();
/* palabras de apellidos (y nombres) compuetos */
$special_tokens = array('DA', 'DE', 'DEL', 'LA', 'LAS', 'LOS', 'MAC', 'MC', 'VAN', 'VON', 'Y', 'I', 'SAN', 'SANTA');
$prev = "";
foreach ($tokens as $token) {
$_token = $token;
if (in_array($_token, $special_tokens)) {
$prev .= "$token ";
} else {
$names[] = $prev . $token;
$prev = "";
}
}
$apellido_paterno = '';
$apellido_materno = '';
$primer_nombre = '';
$segundo_nombre = '';
$validar_name = true;
$num_nombres = count($names);
switch ($num_nombres) {
case 0:
break;
case 1:
$apellido_paterno = $names[0];
break;
case 2:
$apellido_paterno = $names[0];
$primer_nombre = $names[1];
break;
case 3:
$apellido_paterno = $names[0];
$apellido_materno = $names[1];
$primer_nombre = $names[2];
break;
case 4:
$apellido_paterno = $names[0];
$apellido_materno = $names[1];
$primer_nombre = $names[2];
$segundo_nombre = $names[3];
$validar_name = false;
break;
default:
$apellido_paterno = "{$names[0]} {$names[1]}";
$apellido_materno = $names[2];
$primer_nombre = $names[3];
unset($names[0], $names[1], $names[2], $names[3]);
$segundo_nombre = implode(' ', $names);
break;
}
return ['apellido_paterno' => $apellido_paterno, 'apellido_materno' => $apellido_materno, 'primer_nombre' => $primer_nombre, 'segundo_nombre' => $segundo_nombre, 'validar_name' => $validar_name];
}
// En mi archivo donde lo estoy usando, lo obtengo con una Asignación de desestructuración.
['apellido_paterno' => $apellido_paterno, 'apellido_materno' => $apellido_materno, 'primer_nombre' => $primer_nombre, 'segundo_nombre' => $segundo_nombre, 'validar_name' => $validar_name] = splitFullNameToIndividual($full_name);
Excelente ejemplo! muchas gracias! tuve que pasarlo a .Net, en mi caso necesitaba hacerlo con primer nombre y segundo nombre, entonces esto resulte programando por sí a alguien puede servirle ;)
string nombres = $"Deybi";
string apellidos = $"Suanca";
char[] separador = { ' ' };
List<string> nombresLista = ExtractStrings(nombres, separador);
List<string> apellidosLista = ExtractStrings(apellidos, separador);
int num_nombres = nombresLista.Count();
int num_apellidos = apellidosLista.Count();
string primerNombre = "";
string segundoNombre = "";
string primerApellido = "";
string segundoApellido = "";
switch (num_nombres)
{
case 0:
primerNombre = "";
segundoNombre = "";
break;
case 1:
primerNombre = nombresLista[0];
break;
case 2:
primerNombre = nombresLista[0];
segundoNombre = nombresLista[1];
break;
default:
break;
}
switch (num_apellidos)
{
case 0:
primerApellido = "";
segundoApellido = "";
break;
case 1:
primerApellido = apellidosLista[0];
break;
case 2:
primerApellido = apellidosLista[0];
segundoApellido = apellidosLista[1];
break;
default:
break;
}
Console.WriteLine($"Primer nombre: {primerNombre}");
Console.WriteLine($"Segundo nombre: {segundoNombre}");
Console.WriteLine($"Primer apellido: {primerApellido}");
Console.WriteLine($"Segundo apellido: {segundoApellido}");
static List<string> ExtractStrings(string nombres, char[] separador)
{
string[] tokens = nombres.Trim().Split(separador);
string[] tokensEspeciales = { "da", "de", "del", "la", "las", "los", "mac", "mc", "van", "von", "y", "i", "san", "santa" };
string prev = "";
List<string> nombresLista = new List<string>();
foreach (var item in tokens)
{
if (item != "")
{
string actual = item.ToLower();
if (tokensEspeciales.Contains(actual))
{
prev = prev + actual.ToUpper() + " ";
}
else
{
nombresLista.Add(prev + item.ToUpper());
prev = "";
}
}
}
return nombresLista;
}
Hola, he intentado modificar la función para Apps Script, ya que debo obtener por separado nombres y apellidos, algo como nombre1, nombre2, apellido1 y apellido2, pero no lo logro. Alguno ha implementado esta modificación de la función? o, alguien puede, por favor, ayudarme con esto?
Por qué en el "case 3" y "default" pones los apellidos en los índices 0 y 1? Traduje ese código a .NET y en efecto, funciona bien cambiando los índices en ambos case.