Ecco la mia soluzione. Il mio obiettivo non era quello di fornire la soluzione più semplice, ma quella che può assumere una varietà di formati di nome (a volte strani) e generare la migliore ipotesi iniziale e iniziale del nome e del cognome (o nel caso di persone mononime) un'unica iniziale.
Ho anche provato a scrivere in un modo relativamente internazionale-friendly, con unicode regex, anche se non ho alcuna esperienza nel generare le iniziali per molti tipi di nomi stranieri (ad esempio il cinese), anche se dovrebbe meno generare qualcosa di utile per rappresentare la persona, in meno di due caratteri. Ad esempio, darle un nome in coreano come "행운 의 복숭아" produrrà 행복 come ci si sarebbe aspettati (anche se forse non è il modo giusto per farlo nella 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();
}
Sembra non funzionare con caratteri francesi come éè ... Provalo con "Stéphane Test" " Senza questo problema, funziona bene anche con - caracter^_- – Danh
Dovresti modificare il" set "L'ho solo organizzato per funzionare con l'alfabeto inglese standard di 52 caratteri. – Nevyn
Per le iniziali con punti, Michael J. Jordan, è possibile aggiornare l'espressione per includere un "\". Qualcosa di simile "(\ b [a-zA-Z]) [a-zA-Z] * \. *?" – cecilphillip