将名称拆分为字段?

时间:2012-10-17 00:29:01

标签: c# regex

在C#中是否有一个令人惊讶的RegEx或方法可以为我实现这一目标?

有人在“全名”字段中输入字符串,我需要将其分解为: 标题 名字 中间 姓 后缀

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

一个完美的例子是:

John Campbell Smith Jr先生

但是,他们可以:

约翰夫人和玛丽史密斯夫人

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

我认为这对于正则表达来说太复杂了,但是我希望有人可能会有这个想法?

1 个答案:

答案 0 :(得分:5)

好的,这是一个我认为会为你完成工作的程序。你当然可以做一些修改,因为我根据你的问题做了一些假设,但这肯定会让你开始朝着正确的方向前进。

其中一些假设如下:

  1. 在提供给该功能的名称中有 无标点符号 (例如Jr. with the period)。
  2. 必须 有姓名,但标题,中间名和后缀是可选的。
  3. 加入运算符以及& 正如问题中所述。
  4. 此名称的格式为 {titles} {名字} {中间名} {姓名} {后缀}
  5. 我给它扔了很多不同的名字,但肯定有更多的可能性,我没有花费超过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 == "&";
        }
    }