如何提取非大写字符串元素用于名字和姓氏?

3

我有一些形式为字符串的内容

NAME Firstame

我希望能够获取Firstname部分。字符串可能更为复杂(LAST LAST2 First First2)。规则是大写元素是姓氏,其余是名字。我们可以假设第一部分是大写的(=姓氏),当它开始变成混合大小写时,它就是名字,直到结尾。

我相信正确的正则表达式组合[A-Z]\w会起作用。我想到的最好的方法是

import re
re.findall('[A-Z]*\w+', 'LAST LAST2 First First2')

但它返回的解决方案几乎正确(['LAST', 'LAST2', 'First', 'First2']):)

在Python中提取这个名字(们)作为一个字符串的好方法是什么?


使用 '[A-Z][a-z]+' 作为模式怎么样? - falsetru
1
必读文章:程序员对名字的错误认识。此外,\w匹配的内容比你想象的要多,它将匹配大小写字母、数字和下划线 _ - HamZa
1
@HamZa:我知道这篇文章(关于日期也有类似的)。在我的情况下,这只是一个幸运的快速测试,可能会出问题(是的,这样的快速测试最终可能会变成火星车导航系统之类的,但那是另一回事 :))。 - WoJ
4个回答

2
我想提出一个非正则表达式的解决方案:
string = 'LAST LAST2 First First2'
words = string.split(' ') # equals ['LAST', 'LAST2', 'First', 'First2']
result = []
for word in words:
    if not word.isupper():
        result.append(word)
print(' '.join(result))

结果:

First First2

你比我更先进。如果你可以不使用正则表达式来完成某些事情,我认为最好不要使用它们。 - Denis Nikanorov

1
使用正则表达式:
import re
s = 'LAST LAST2 First First2'
print re.search("[A-Z][a-z].*$",s).group().split()
  • [A-Z] 匹配一个在 A 和 Z 范围内的单个字符(区分大小写)
  • [a-z] 匹配一个在 a 和 z 范围内的单个字符(区分大小写)
  • .* 匹配任何字符(换行符除外)。量词:零次或多次,尽可能多地匹配 [贪婪模式]
  • $ 断言当前位置在字符串的结尾

非正则表达式

s = 'LAST LAST2 First First2'
print [i for i in s.split() if not i.isupper()]

[out]:

['First', 'First2']

谢谢 - 非正则表达式的那个很棒(我得学习这些 [...] 结构,它们将美丽的 Python 代码变成了像 Perl 一样的神秘代码 :)) - WoJ
它们被称为列表推导式。作为来自C/C++背景的人,起初我认为这是魔法。现在我知道它是一种奇妙的“黑”魔法。 - alvas
我也是。我正要编辑我的评论,以提供你提到的正确名称(以及指向文档的指针)。 - WoJ

0

尝试:

import re
re.findall('\b[A-Z][a-z0-9_-]+', 'LAST LAST2 First First2')

这将导致:

# Run findall
>>> regex.findall(string)
[u'First', u'First2']

代码引发异常:sre_constants.error: 模式意外结束 - falsetru
你是对的,我忘了Python不允许使用(?-i)来声明大小写敏感性。已更新答案。 - JonM

0

这段代码能帮到你吗:

re.search("[A-Z][a-z].*$","LAST LAST2 First First2").group()

或者它可以更加健壮:

re.search("(?<= )[A-Z][^A-Z][\w|\s]*$","LAST LAST2 First First2").group()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接