可靠地转换逗号/分号分隔的“last,first,last,first”名称列表

2024-04-16 23:32:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个很大的名字列表,包含多个名字的条目用逗号或分号分隔,有时甚至不用。例如:

First Last
Last, First
Last, First, A.
Last, First Middle
Last, First, Last, First A., Last, First, Ph.D, Last, First, M.D., Last, J. R, Last, O.
Last, First Middle plus other names, Last, First, Jr., Last, First, Sr.
Last, First; Last, First A.; Last, First Middle 
First Last, First Last, First A. Last, Last, First

我正在尝试创建一个函数,当我分别传入每个条目时,它将可靠地返回一个列表,所有内容都正确地排序为“First Last”,并带有任何可能的后缀,如Jr、m.D等。到目前为止,从另一个So问题来看,我有:

def fix_names(names):
    if ',' in names:
        names = [b.strip() + ' ' + a.strip()
                   for a, b in zip(*[iter(names.split(','))] * 2)]
    return names

最后我想说:

['First Last']
['First Last', 'First A. Last', 'First Last, Ph.D', 'First Last, Jr.'] etc

如果我先去掉诸如“M.D”之类的后缀,然后不保留它们,大多数情况下都是有效的。例如,举一个没有前缀的例子:

Last, First, Last, First A., Last, First, Last, First, Last, J. R., Last, O.

我得到:

['First Last', 'First A. Last', 'First Last', 'First Last', 'J. R. Last', 'O. Last']

还有一个例子,比如“Last,First A.”,结果是['First Last']。对于可能是“先到最后,先到最后”的情况,我不一定介意是否反转,因为这种情况比较少见,如果需要,我可以稍后再修复。我还将分步处理分号和逗号,因为我不确定是否容易拆分一次,然后遍历每个值,如果需要再次拆分,则添加到列表中。你知道吗


Tags: inmiddle列表names情况条目名字后缀
1条回答
网友
1楼 · 发布于 2024-04-16 23:32:23

这是一个很难解析的问题,但这里有一个大致的草图,它做得相当好。你知道吗

import sys
import re

SUFFIXES = set('''
    Ph.D
    M.D.
    Jr.
    Sr.
'''.split())

regexes = dict(
    punct  = re.compile(r'\s*[;,]\s*'),
    space  = re.compile(r'\s*'),
    middle = re.compile(r'^[A-Z]\.?$'),
)

def main(file_path):
    with open(file_path) as fh:
        for line in fh:
            for name in parse_line(line):
                print name

def parse_line(line):
    tokens = get_tokens(line.strip())
    name = []
    for t in tokens:
        if t in SUFFIXES:
            name.append(t)
        elif regexes['middle'].search(t):
            name.append(t)
        elif len(name) > 1:
            yield name
            name = [t]
        else:
            name.append(t)
    if name:
        yield name

def get_tokens(line):
    k = 'punct' if (';' in line or ',' in line) else 'space'
    return regexes[k].split(line.strip())

main(sys.argv[1])

结果并不完美。现在还不清楚,如果不在算法中加入更多的名称智能,如何区分下面的三个问题案例注释(#1、#2和#3)。当您看到一个包含空格的标记时,它是第一个中间组合还是第一个最后一个组合?这种模棱两可的情况会破坏将标记组合在一起以形成一个人的名字的逻辑。你可以检查代币上是否有空格:如果有的话,就把它分开(这可以解决#2和#3),但这会使#1更糟。你知道吗

['First', 'Last']
['Last', 'First']
['Last', 'First', 'A.']
['Last', 'First Middle']
['Last', 'First']
['Last', 'First A.']
['Last', 'First', 'Ph.D']
['Last', 'First', 'M.D.']
['Last', 'J. R']
['Last', 'O.']
['Last', 'First Middle plus other names']    # 1
['Last', 'First', 'Jr.']
['Last', 'First Sr.']
['Last', 'First']
['Last', 'First A.']
['Last', 'First Middle']
['First Last', 'First Last']                 # 2
['First A. Last', 'Last']
['First']                                    # 3

相关问题 更多 >