Aquí está mi solución. Mi objetivo no era proporcionar la solución más simple, sino una que puede tomar una variedad de formatos de nombres (a veces extraños), y generar la mejor estimación en una inicial de nombre y apellido (o en el caso de personas monónimas) una sola inicial.
También traté de escribirlo de una manera relativamente internacionalmente amigable, con expresiones regulares unicode, aunque no tengo ninguna experiencia en generar iniciales para muchos tipos de nombres extranjeros (por ejemplo, chino), aunque debería hacerlo en Al menos genere algo utilizable para representar a la persona, en menos de dos caracteres. Por ejemplo, al darle un nombre en coreano como "행운 의 will" se obtendrá 행복 como podría haber esperado (aunque tal vez esa no sea la forma correcta de hacerlo en la cultura coreana).
/// <summary>
/// Given a person's first and last name, we'll make our best guess to extract up to two initials, hopefully
/// representing their first and last name, skipping any middle initials, Jr/Sr/III suffixes, etc. The letters
/// will be returned together in ALL CAPS, e.g. "TW".
///
/// The way it parses names for many common styles:
///
/// Mason Zhwiti -> MZ
/// mason lowercase zhwiti -> MZ
/// Mason G Zhwiti -> MZ
/// Mason G. Zhwiti -> MZ
/// John Queue Public -> JP
/// John Q. Public, Jr. -> JP
/// John Q Public Jr. -> JP
/// Thurston Howell III -> TH
/// Thurston Howell, III -> TH
/// Malcolm X -> MX
/// A Ron -> AR
/// A A Ron -> AR
/// Madonna -> M
/// Chris O'Donnell -> CO
/// Malcolm McDowell -> MM
/// Robert "Rocky" Balboa, Sr. -> RB
/// 1Bobby 2Tables -> BT
/// Éric Ígor -> ÉÍ
/// 행운의 복숭아 -> 행복
///
/// </summary>
/// <param name="name">The full name of a person.</param>
/// <returns>One to two uppercase initials, without punctuation.</returns>
public static string ExtractInitialsFromName(string name)
{
// first remove all: punctuation, separator chars, control chars, and numbers (unicode style regexes)
string initials = Regex.Replace(name, @"[\p{P}\p{S}\p{C}\p{N}]+", "");
// Replacing all possible whitespace/separator characters (unicode style), with a single, regular ascii space.
initials = Regex.Replace(initials, @"\p{Z}+", " ");
// Remove all Sr, Jr, I, II, III, IV, V, VI, VII, VIII, IX at the end of names
initials = Regex.Replace(initials.Trim(), @"\s+(?:[JS]R|I{1,3}|I[VX]|VI{0,3})$", "", RegexOptions.IgnoreCase);
// Extract up to 2 initials from the remaining cleaned name.
initials = Regex.Replace(initials, @"^(\p{L})[^\s]*(?:\s+(?:\p{L}+\s+(?=\p{L}))?(?:(\p{L})\p{L}*)?)?$", "$1$2").Trim();
if (initials.Length > 2)
{
// Worst case scenario, everything failed, just grab the first two letters of what we have left.
initials = initials.Substring(0, 2);
}
return initials.ToUpperInvariant();
}
Parece que no funciona con el caracter francés como é ... Pruebe con "Stéphane Test " Sin ese problema, funciona bien incluso con - caracter^_- – Danh
Tendría que modificar el" conjunto "Solo lo arreglé para que funcione con el alfabeto inglés americano estándar de 52 caracteres. – Nevyn
Para las iniciales con puntos, Michael J. Jordan, puede actualizar la expresión para incluir un "\". Algo como esto "(\ b [a-zA-Z]) [a-zA-Z] * \. *?" – cecilphillip