【问题标题】:Splitting List of Names where there Might Be Common Last Name for Two First Names拆分两个名字可能有共同姓氏的名字列表
【发布时间】:2015-03-08 05:01:16
【问题描述】:

在 Python 中,我正在解析大量名称,如下所示:

[u' Ron Iervolino, Trish Iervolino, Russ Middleton, and Lisa Middleton ',
 u' Barbara Loughlin, Dr. Gerald Loughlin, and Debbie Gelston ',
 u' Julianne Michelle 
    ... ']

我可以使用以下方法将它们拆分为单独的名称:

re.split('(([A-Z]\.?\s?)*([A-Z][a-z]+\.?\s?)+([A-Z]\.?\s?[a-z]*)*)', line)[1::5]

例如,如果我在上面示例数据的第一个位置调用它,它会返回:

[u'Ron Iervolino', u'Trish Iervolino', u'Russ Middleton', u'Lisa Middleton ']

酷。这适用于很多情况。我遇到的问题是,在某些情况下,名称的格式如下:

[   ...,
 u' Kelly  and Tom Murro ',
    ...]

这里指的是 Kelly Murro 和 Tom Murro。关于如何指出我匹配这个特殊情况的任何想法?我有一个执行正则表达式操作的函数(调用 re.split),所以我的想法是添加到这个函数中并首先检查该事件是否存在。如果列表中有两个以上的姓名,则看起来好像姓氏与两个名字配对。仅当列表中同时存在两个(并且只有两个)名称并且它们共享姓氏时,才会出现这种情况。

编辑

我喜欢“alpha bravo”解决方案的简单性。为了了解正在发生的事情,我弄乱了 Regex101 站点演示并让它生成了一些代码。代码似乎没有做任何事情,也许我的大脑因为盯着这个时间太久而融化了。有什么建议吗?

import re
p = re.compile(ur'([A-Z]\w+\s+[A-Z]\w+)|([A-Z]\w+)(?=\s+and\s+[A-Z]\w+\s+([A-Z]\w+))', re.MULTILINE)
test_str = u"Russ Middleton and Lisa Murro\nRon Iervolino, Trish and Russ Middleton, and Lisa Middleton \nRon Iervolino, Kelly  and Tom Murro\nRon Iervolino, Trish and Russ Middleton and Lisa Middleton "
subst = u"$1$2 $3"

result = re.sub(p, subst, test_str)

变量result 只是替换字符串。

【问题讨论】:

  • 解决这个问题的防弹方法是编写一个简单的解析器。

标签: python html regex python-2.7


【解决方案1】:

作为第一次匹配的更有效方式,您可以使用 str.split()(如果您的字符串已使用 , 拆分):

>>> s=u' Ron Iervolino, Trish Iervolino, Russ Middleton, and Lisa Middleton '
>>> [i.split('and')[1] if i.strip().startswith('and') else i for i in s.split(',')]
[u' Ron Iervolino', u' Trish Iervolino', u' Russ Middleton', u' Lisa Middleton ']

要在u' Kelly and Tom Murro ' 中查找名称,您可以使用以下内容:

l=[]
s=u' Ron Iervolino, Trish Iervolino, Russ Middleton, and Lisa Middleton ,Kelly  and Tom Murro'
import re
for i in s.split(','):
   i=i.strip()
   if i.startswith('and') :
      l.append(i.split('and')[1])
   elif not i.endswith('and') and 'and' in i :
      names=[i for i in re.split(r'and| ',i) if i]
      for t in zip(names[:-1],[names[-1] for i in range(len(names)-1)]):
          l.append(' '.join(t))
   else: 
      l.append(i)

print l
[u'Ron Iervolino', u'Trish Iervolino', u'Russ Middleton', u' Lisa Middleton', u'Kelly  Murro', u'Tom  Murro']

当您遇到像 u' Kelly and Tom Murro ' 这样的字符串时,首先将其拆分为带有 [i for i in re.split(r'and| ',i) if i] 的名称列表,该列表基于 'and'space 拆分字符串,因此您将拥有 [u'Kelly', u'Tom', u'Murro']。然后你想要以下名称:

u'Kelly  Murro'
u'Tom  Murro'

您可以创建一个 zip 文件,其中重复最后一个元素,并从列表的开头到最后一个命名names[:-1],这样您将拥有以下内容。 请注意,此配方适用于最长的名字,例如 (Kelly and Tom and rose and sarah Murro):

[(u'Kelly', u'Murro'), (u'Tom', u'Murro')]

【讨论】:

    【解决方案2】:

    这应该给你一个想法,先使用这个模式

    ([A-Z]\w+\s+[A-Z]\w+)|([A-Z]\w+)(?=\s+and\s+[A-Z]\w+\s+([A-Z]\w+))
    

    并替换为$1$2 $3
    Demo

    【讨论】:

    • 我真的很喜欢它的简单性,谢谢!现在尝试让实现工作。
    猜你喜欢
    • 2015-12-21
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多