2012-05-30 22 views
6
eg. if the Name is: John Deer 
the Initials should be: JD 

Posso usare le sottostringhe per eseguire questo controllo sul campo Iniziali, ma mi chiedo se posso scrivere un'espressione regolare per questo? E scrivere un'espressione regolare è un'idea migliore del farlo usando i metodi delle stringhe?Regex per estrarre le iniziali da Nome

risposta

13

Personalmente, preferisco questo Regex

Regex initials = new Regex(@"(\b[a-zA-Z])[a-zA-Z]* ?"); 
string init = initials.Replace(nameString, "$1"); 
//Init = "JD" 

che si prende cura di iniziali, e la rimozione spazi bianchi (questo è il '?' Alla fine c'è).

L'unica cosa di cui ti devi preoccupare sono i titoli e il popping come Jr. o Sr., o Mrs .... ecc. Ecc.Alcune persone fanno includere quelli nei loro nomi completi

+0

Sembra non funzionare con caratteri francesi come éè ... Provalo con "Stéphane Test" " Senza questo problema, funziona bene anche con - caracter^_- – Danh

+0

Dovresti modificare il" set "L'ho solo organizzato per funzionare con l'alfabeto inglese standard di 52 caratteri. – Nevyn

+0

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

2

ne dici di questo?

var initials = Regex.Replace("John Deer", "[^A-Z]", ""); 
+0

Tuttavia, Harrold McDonnald uscirà come HMD – IanNorton

+0

Funzionerà solo se il nome è in maiuscolo ... – Jay

0

Sì, utilizzare un'espressione regolare. È possibile utilizzare i metodi Regex.Match e Regex.Match.Groups per trovare le corrispondenze e quindi per estrarre i valori corrispondenti necessari, le iniziali in questo caso. Trovare ed estrarre i valori avverrà nello stesso momento.

0

[a-z]+[a-z]+\b che sarà netto che le prime due lettere di ogni nome ...

dove name = 'Greg Henry' = 'GH' o 'James Smith' 'JS'

Poi è possibile dividere su '' e di unirsi a ''

Questo funziona anche su nomi come

'James Henry George Michael' = 'JHGM'

'James Henry George Michael III il secondo'= 'JHGM III'

Se si vuole evitare la scissione utilizzare [a-z]+[a-z]+\b ?

Ma poi nomi come Jon Michael Jr. The 3rd saranno = JMJr.T3 in cui l'opzione di cui sopra consente di ottenere 'The', 'the' e '3rd' se lo si desidera ..

Se si voleva davvero essere fantasioso, è possibile utilizzare lo (\b[a-zA-Z])[a-zA-Z]* ? per abbinare solo le parti del nome e quindi sostituirlo con il primo.

0

ne dite di questo:

 string name = "John Clark MacDonald"; 
     var parts = name.Split(' '); 
     string initials = ""; 

     foreach (var part in parts) 
     { 
      initials += Regex.Match(part, "[A-Z]"); 
      Console.WriteLine(part + " --> " + Regex.Match(part,"[A-Z]")); 
     } 
     Console.WriteLine("Final initials: " + initials); 
     Console.ReadKey(); 

Questo permette di secondi nomi opzionali, e lavora per più capitalizzazioni, come indicato sopra.

1

Ecco un'alternativa con l'accento sulla mantenerlo semplice:

/// <summary> 
    /// Gets initials from the supplied names string. 
    /// </summary> 
    /// <param name="names">Names separated by whitespace</param> 
    /// <param name="separator">Separator between initials (e.g. "", "." or ". ") </param> 
    /// <returns>Upper case initials (with separators in between)</returns> 
    public static string GetInitials(string names, string separator) 
    { 
     // Extract the first character out of each block of non-whitespace 
     Regex extractInitials = new Regex(@"\s*([^\s])[^\s]*\s*"); 
     return extractInitials.Replace(names, "$1" + separator).ToUpper(); 
    } 

C'è una domanda di cosa fare se i nomi non sono forniti come previsto. Personalmente penso che dovrebbe solo restituire il primo carattere da ogni blocco di testo che non è uno spazio bianco. Per esempio:

1Steve 2Chambers    => 12 
harold mcDonald    => HM 
David O'Leary     => DO 
David O' Leary     => DOL 
Ronnie "the rocket" O'Sullivan => R"RO 

Ci saranno quelli che avevano sostengono per le tecniche più sofisticate/complessi (ad esempio, per gestire l'ultimo meglio), ma IMO questo è davvero un problema di pulizia dei dati.

+0

Sembra molto gentile signore. Ho trovato un cheat sheet per Regexes in C# qui btw: http://www.mikesdotnetting.com/article/46/c-regular-expressions-cheat-sheet –

13

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(); 
} 
+0

Mason molto ben fatto. Mentre ho provato solo contro i nomi in inglese, funziona e copre una varietà di scenari. – Aggromonster