【问题标题】:How to extract non-uppercase string elements for first and last names?如何提取名字和姓氏的非大写字符串元素?
【发布时间】:2014-01-06 10:05:31
【问题描述】:

我有表单的字符串

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]+'作为模式怎么样?
  • 必读article。此外,\w 匹配的内容比您想象的要多,它将匹配大小写字母、数字和下划线 _
  • @HamZa:我知道这篇文章(dates 上也有类似的文章)——幸运的是,这只是一个可以打破的快速测试(是的,这样的快速测试然后变成火星漫游者导航系统或其他东西,但那是另一回事:))

标签: python regex string extract


【解决方案1】:

我想提出一个非正则表达式的解决方案:

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

【讨论】:

  • 你领先于我((如果你可以在没有 regexp 的情况下简单地做某事,我认为最好没有它们就这样做
【解决方案2】:

使用正则表达式:

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()]

[出]:

['First', 'First2']

【讨论】:

  • 谢谢 - 非正则表达式很棒(我必须了解这些 [...] 构造,它们将漂亮的 Python 代码变成神秘的类似 Perl 的代码:))
  • 他们是调用列表理解。来自 C/C++ 背景,起初我认为它很神奇。现在我知道这是创造奇迹的“黑”魔法。
  • 对我来说也一样。我正要编辑我的评论以提供您提到的正确名称(以及pointer to the docs
【解决方案3】:

试试:

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: unexpected end of pattern
  • 你说得对,我忘了 python 不喜欢 (?-i) 声明区分大小写。已更新答案。
【解决方案4】:

这段代码对你有帮助吗:

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

或者它可以更健壮:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 2018-02-28
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多