2012-10-17 69 views
4

C#中有没有令人惊叹的RegEx或方法可能为我实现这一点?将字段拆分成字段?

有人类型的字符串转换成“全名”字段,我需要把它分解成: 标题 姓 中东 姓 后缀

但是,用户可以输入“约翰·史密斯”,所以它需要把约翰放入名字,史密斯放入姓氏。一个人可以输入John Smith先生(我有一个已知的标题和后缀列表),所以如果第一个字符串是标题,它会进入Title字段。

一个很好的例子是:

先生约翰·坎贝尔·史密斯JR

但是,他们可以有:

先生和夫人约翰和玛丽·史密斯

所以标题是先生和夫人,名字是约翰和玛丽,姓氏是史密斯(他们可以使用“和”或“&”作为木匠)

我很吝惜这对于正则表达式来说太复杂了,但我希望有人可能有一个想法?

+7

http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/ –

+8

我投 “使用不同的领域”。 –

+1

真棒链接@AustinSalonen –

回答

5

好的,这里是一个我认为能为你做的工作。你当然可以做一些修改,因为我根据你的问题做了一些假设,但是这肯定会让你开始朝正确的方向发展。

其中一些假设如下:

  1. 没有标点符号在提供给功能(例如与小的期间)的名称。
  2. 必须有姓和名,但标题,中间名和后缀是可选的。
  3. 只有加入运营商&就像在问题说明。
  4. 该名称的格式为{titles} {first name} {middle name} {last name} {suffix}

我扔了很多不同的名字吧,但肯定有更多的可能性,我没有花任何超过30分钟,在这所以它不是完全测试

class Program 
{ 
    static List<string> _titles = new List<string> { "Mr", "Mrs", "Miss" }; 
    static List<string> _suffixes = new List<string> { "Jr", "Sr" }; 

    static void Main(string[] args) 
    { 
     var nameCombinations = new List<string> 
     { 
      "Mr and Mrs John and Mary Sue Smith Jr", 
      "Mr and Mrs John and Mary Smith Jr", 
      "Mr and Mrs John and Mary Sue Smith", 
      "Mr and Mrs John and Mary Smith", 
      "Mr and Mrs John Smith Jr", 
      "Mr and Mrs John Smith", 
      "John Smith", 
      "John and Mary Smith", 
      "John and Mary Smith Jr", 
      "Mr John Campbell Smith Jr", 
      "Mr John Smith", 
      "Mr John Smith Jr", 
     }; 

     foreach (var name in nameCombinations) 
     { 
      Console.WriteLine(name); 

      var breakdown = InterperetName(name); 

      Console.WriteLine(" Title(s):  {0}", string.Join(", ", breakdown.Item1)); 
      Console.WriteLine(" First Name(s): {0}", string.Join(", ", breakdown.Item2)); 
      Console.WriteLine(" Middle Name: {0}", breakdown.Item3); 
      Console.WriteLine(" Last Name:  {0}", breakdown.Item4); 
      Console.WriteLine(" Suffix:   {0}", breakdown.Item5); 

      Console.WriteLine(); 
     } 

     Console.ReadKey(); 
    } 

    static Tuple<List<string>, List<string>, string, string, string> InterperetName(string name) 
    { 
     var segments = name.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 

     List<string> titles = new List<string>(), 
      firstNames = new List<string>(); 
     string middleName = null, lastName = null, suffix = null; 
     int segment = 0; 

     for (int i = 0; i < segments.Length; i++) 
     { 
      var s = segments[i]; 

      switch (segment) 
      { 
       case 0: 
        if (_titles.Contains(s)) 
        { 
         titles.Add(s); 
         if (segments[i + 1].IsJoiner()) 
         { 
          i++; 
          continue; 
         } 

         segment++; 
        } 
        else 
        { 
         segment++; 
         goto case 1; 
        } 

        break; 
       case 1: 
        firstNames.Add(s); 
        if (segments[i + 1].IsJoiner()) 
        { 
         i++; 
         continue; 
        } 

        segment++; 

        break; 
       case 2: 
        if ((i + 1) == segments.Length) 
        { 
         segment++; 
         goto case 3; 
        } 
        else if ((i + 2) == segments.Length && _suffixes.Contains(segments[i + 1])) 
        { 
         segment++; 
         goto case 3; 
        } 

        middleName = s; 
        segment++; 

        break; 
       case 3: 
        lastName = s; 
        segment++; 

        break; 
       case 4: 
        if (_suffixes.Contains(s)) 
        { 
         suffix = s; 
        } 

        segment++; 

        break; 
      } 
     } 

     return new Tuple<List<string>, List<string>, string, string, string>(titles, firstNames, middleName, lastName, suffix); 
    } 
} 

internal static class Extensions 
{ 
    internal static bool IsJoiner(this string s) 
    { 
     var val = s.ToLower().Trim(); 
     return val == "and" || val == "&"; 
    } 
} 
+0

工作得非常好。它实际上遵循了我们正在走向的模式,但我们失败了。你的完美!感谢BigM – Craig

+0

@克雷格,太棒了!我很高兴我能得到帮助! –

+1

对于你投入这个答案的时间量它值得更多upvotes – splatto