当前位置:  开发笔记 > 编程语言 > 正文

将人名称解析为组成部分的简单方法?

如何解决《将人名称解析为组成部分的简单方法?》经验,为你挑选了4个好方法。

许多联系人管理程序都这样做 - 你输入一个名字(例如,"John W. Smith"),它会自动将其分解为:

名字:约翰
中间名: W.
姓:史密斯

同样,它也会找出像"简·史密斯夫人"和"约翰·多伊博士"这样的事情.也正确(假设您允许名称中包含"prefix"和"suffix"等字段).

我认为这是人们想要做的相当普遍的事情......所以问题是......你会怎么做?有一个简单的算法吗?也许正则表达式?

我正在使用.NET解决方案,但我并不挑剔.

更新:我感谢没有简单的解决方案可以涵盖所有边缘案例和文化...但是,为了论证,你需要说明你需要这个名字(填写表格 - 比如说,税收或其他政府表格 - 是一种情况,您必须将名称输入固定字段,无论您是否喜欢),但您不一定要强迫用户将其名称输入到离散字段中(减少输入=更容易新手用户).

你想让程序"猜测"(尽可能最好)在第一个,中间的,最后一个等等.如果可以的话,看看Microsoft Outlook如何为联系人做这个 - 它让你输入名字,但是如果你需要澄清,你可以打开一个额外的小窗口.我会做同样的事情 - 给用户提供窗口以防他们想要以离散的部分输入名称 - 但允许在一个框中输入名称并进行涵盖大多数常见名称的"最佳猜测" .



1> shadit..:

如果你必须进行这种解析,我相信你会在这里得到很多好的建议.

我的建议是 - 不要做这个解析.

而是创建输入字段,以便信息已经分离出来.有标题,名字,中间名,姓氏,后缀等单独的字段.



2> eselk..:

我知道这是旧的,可​​能是我已经找不到的地方的答案,但由于我找不到任何对我有用的东西,这就是我提出的,我认为它与Google Contacts和Microsoft Outlook非常相似.它不能很好地处理边缘情况,但对于一个好的CRM类型的应用程序,总是可以要求用户解决这些问题(在我的应用程序中我实际上一直有单独的字段,但我需要这个来从另一个应用程序导入数据只有一个字段):

    public static void ParseName(this string s, out string prefix, out string first, out string middle, out string last, out string suffix)
    {
        prefix = "";
        first = "";
        middle = "";
        last = "";
        suffix = "";

        // Split on period, commas or spaces, but don't remove from results.
        List parts = Regex.Split(s, @"(?<=[., ])").ToList();

        // Remove any empty parts
        for (int x = parts.Count - 1; x >= 0; x--)
            if (parts[x].Trim() == "")
                parts.RemoveAt(x);

        if (parts.Count > 0)
        {
            // Might want to add more to this list
            string[] prefixes = { "mr", "mrs", "ms", "dr", "miss", "sir", "madam", "mayor", "president" };

            // If first part is a prefix, set prefix and remove part
            string normalizedPart = parts.First().Replace(".", "").Replace(",", "").Trim().ToLower();
            if (prefixes.Contains(normalizedPart))
            {
                prefix = parts[0].Trim();
                parts.RemoveAt(0);
            }
        }

        if (parts.Count > 0)
        {
            // Might want to add more to this list, or use code/regex for roman-numeral detection
            string[] suffixes = { "jr", "sr", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "xi", "xii", "xiii", "xiv", "xv" };

            // If last part is a suffix, set suffix and remove part
            string normalizedPart = parts.Last().Replace(".", "").Replace(",", "").Trim().ToLower();
            if (suffixes.Contains(normalizedPart))
            {
                suffix = parts.Last().Replace(",", "").Trim();
                parts.RemoveAt(parts.Count - 1);
            }
        }

        // Done, if no more parts
        if (parts.Count == 0)
            return;

        // If only one part left...
        if (parts.Count == 1)
        {
            // If no prefix, assume first name, otherwise last
            // i.e.- "Dr Jones", "Ms Jones" -- likely to be last
            if(prefix == "")
                first = parts.First().Replace(",", "").Trim();
            else
                last = parts.First().Replace(",", "").Trim();
        }

        // If first part ends with a comma, assume format:
        //   Last, First [...First...]
        else if (parts.First().EndsWith(","))
        {
            last = parts.First().Replace(",", "").Trim();
            for (int x = 1; x < parts.Count; x++)
                first += parts[x].Replace(",", "").Trim() + " ";
            first = first.Trim();
        }

        // Otherwise assume format:
        // First [...Middle...] Last

        else
        {
            first = parts.First().Replace(",", "").Trim();
            last = parts.Last().Replace(",", "").Trim();
            for (int x = 1; x < parts.Count - 1; x++)
                middle += parts[x].Replace(",", "").Trim() + " ";
            middle = middle.Trim();
        }
    }

对不起,代码很长很难看,我还没有去清理它.它是一个C#扩展,所以你会像以下一样使用它:

string name = "Miss Jessica Dark-Angel Alba";
string prefix, first, middle, last, suffix;
name.ParseName(out prefix, out first, out middle, out last, out suffix);



3> Stephen Deke..:

对此没有简单的解决方案.名称构造因文化而异,甚至在英语世界中也有前缀和后缀,这些前缀和后缀不一定是名称的一部分.

一个基本的方法是在字符串的开头寻找敬意(例如,"Hon.John Doe")和最后的数字或其他字符串(例如,"John Doe IV","John Doe Jr."),但是你所能做的就是应用一套启发式方法,并希望最好.

查找未处理名称列表并根据它测试算法可能很有用.不过,我不知道那里有什么预先包装好的东西.



4> Vincent McNa..:

你可能不需要做任何真正的事情.这样的事情应该有效.

    Name = Name.Trim();

    arrNames = Name.Split(' ');

    if (arrNames.Length > 0) {
        GivenName = arrNames[0];
    }
    if (arrNames.Length > 1) {
        FamilyName = arrNames[arrNames.Length - 1];
    }
    if (arrNames.Length > 2) {
        MiddleName = string.Join(" ", arrNames, 1, arrNames.Length - 2);
    }

您可能还想先检查标题.


是的,名字很难
这对于"McNabb,Vincent"格式的名称不起作用.
推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有