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

Mogę użyć podciągów, aby wykonać to sprawdzanie w polu Inicjały, ale zastanawiam się, czy mogę napisać dla niego wyrażenie regularne? Czy pisanie wyrażenia regularnego jest lepszym pomysłem niż wykonywanie go za pomocą metod łańcuchów?Regex do wyodrębniania inicjałów od Nazwa

Odpowiedz

13

Osobiście wolę ten Regex

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

która dba o inicjałach i białymi usunięcia (Ów „?” Na końcu tam).

Jedyna rzecz, o którą musisz się martwić, to tytuły i paktyacje, takie jak Jr. lub Sr., lub Mrs .... itd.Niektórzy ludzie są te, w ich pełnych nazw

+0

Wygląda na to, że nie działa z francuską wersją typu èè ... Spróbuj z "Stéphane Test" " Bez tego problemu, działa dobrze nawet z - caracter^_- – Danh

+0

Musiałbyś zmodyfikować" zestaw ", który ustawiłem tylko do pracy ze standardowym amerykańskim alfabetem z 52 literami. – Nevyn

+0

W przypadku inicjałów z kropkami, Michael J. Jordan, można zaktualizować wyrażenie tak, aby zawierało znak "\.". Coś podobnego do tego "(\ b [a [z-Z]) [a-zA-Z] * \. *?" – cecilphillip

2

Jak na ten temat?

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

Nie zapomnijcie jednak o wszystkich tych Scottach, Harrold McDonnald wyjdzie jako HMD – IanNorton

+0

Działa tylko wtedy, gdy nazwa jest pisana wielką literą ... – Jay

0

Tak, użyj wyrażenia regularnego. Możesz użyć metod Regex.Match i Regex.Match.Groups w celu znalezienia dopasowań, a następnie wyodrębnienia pasujących wartości, których potrzebujesz - w tym przypadku inicjałów. Wyszukiwanie i wyodrębnianie wartości będzie odbywało się w tym samym czasie.

0

[a-z]+[a-z]+\b który złowi wam dwie pierwsze litery nazwy każdego ...

gdzie name = 'Gregg Henry' = 'GH' lub 'James Smith' 'JS'

Następnie można podzielić na '' i dołącz na ''

To działa nawet na nazwach jak

James Henry George Michael '= 'JHGM'

„James Henry George Michael III drugi”=«JHGM III»

Jeśli chcesz uniknąć podział wykorzystują [a-z]+[a-z]+\b ?

Ale wtedy takie nazwy, jak Jon Michael Jr. The 3rd będzie = JMJr.T3 gdzie jak powyższa opcja pozwala uzyskać zwaną dalej" "the" i "3rd", jeśli chcesz ..

Jeśli naprawdę chciałeś się podobać, możesz użyć (\b[a-zA-Z])[a-zA-Z]* ?, aby dopasować tylko części nazwy, a następnie zastąpić je pierwszym.

0

Jak o tym:

 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(); 

Pozwala to na dodatkowe drugie imię, a pracuje dla wielu kapitalizacji, jak pokazano powyżej.

1

Oto alternatywna z naciskiem na utrzymanie go prosta:

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

Jest to kwestia, co zrobić, jeśli dostarczone nazwy nie są zgodnie z oczekiwaniami. Osobiście uważam, że powinien po prostu zwrócić pierwszy znak z każdego fragmentu tekstu, który nie jest odstępem. Np:

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

Nie będzie tych, którzy twierdzą, że dla bardziej zaawansowanych/skomplikowanych technik (np obsługiwać ostatni lepiej), ale IMO to jest naprawdę kwestia czyszczenia danych.

+0

Wygląda bardzo ładnie Sir. Znalazłem ściągawki dla Regexes w C# tutaj btw: http://www.mikesdotnetting.com/article/46/c-regular-expressions-cheat-sheet –

13

Oto moje rozwiązanie. Moim celem nie było dostarczenie najprostszego rozwiązania, ale takiego, które może przyjmować różnorodne (czasem dziwne) formaty nazw i generować najlepsze przypuszczenia na początku i na końcu nazwiska (lub w przypadku osób mononimicznych) na pojedynczy inicjał.

Próbowałem również napisać to w sposób, który jest względnie międzynarodowy, z wyrażeń regularnych unicode, chociaż nie mam żadnego doświadczenia w generowaniu inicjałów dla wielu zagranicznych nazw (np. Chińskich), choć powinno to być najmniej wygenerować coś użytecznego do reprezentowania osoby, poniżej dwóch znaków. Na przykład, podanie nazwy w języku koreańskim, jak "행운 의 복숭아", przyniesie 행복, jak można się było spodziewać (chociaż być może nie jest to właściwy sposób w koreańskiej kulturze).

/// <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

Bardzo dobrze zrobiony Mason. Chociaż testowałem tylko nazwy w języku angielskim, to działa i obejmuje różne scenariusze. – Aggromonster

Powiązane problemy