Python 如何从格式一致的字符串列表中提取ID号

Python 如何从格式一致的字符串列表中提取ID号,python,string,Python,String,我正在处理一组数据,这些数据的名称和用户名组合在一个字符串中。例如,如果用户名为“John Smith”,其ID号为1234567,则字符串将为“John Smith---1234567”。字符串的格式一致,始终为: NAME [space] 3 HYPHENS [space] ID number 我试图找到一种从这些字符串中提取ID号的方法。我发现做这样的事情: foo = "John Smith --- 1234567" bar = [str(s) for s in foo.split(

我正在处理一组数据,这些数据的名称和用户名组合在一个字符串中。例如,如果用户名为“John Smith”,其ID号为1234567,则字符串将为“John Smith---1234567”。字符串的格式一致,始终为:

NAME [space] 3 HYPHENS [space] ID number
我试图找到一种从这些字符串中提取ID号的方法。我发现做这样的事情:

foo = "John Smith --- 1234567"

bar = [str(s) for s in foo.split() if s.isdigit()]
>>> data = "John Smith --- 1234567"
>>> idtext = data.rsplit(' --- ', 1)[1]
>>> int(idtext)
1234567
我得到了这样一个列表['1234567']。这将满足我的需要,但我想知道是否有一种更“Pythonic”/clean的方法来做到这一点?有没有一种方法可以直接获取返回的ID号和int,而不是一个包含字符串的列表?

如何:

bar = [int(s) for s in foo.split() if s.isdigit()]
相反?

那么:

bar = [int(s) for s in foo.split() if s.isdigit()]

相反?

您可以在这种情况下使用正则表达式

import re
foo = "John Smith --- 1234567"
id = re.search(r'\d+',foo).group()

对于这种情况,可以使用正则表达式

import re
foo = "John Smith --- 1234567"
id = re.search(r'\d+',foo).group()

正则表达式的适当使用是“Pythonic”:

正则表达式要求输入任何序列,后跟“--”标记,后跟数字,然后是行尾。这可能限制太多,或者限制不够,具体取决于实际数据

这是否适合您的情况,以及您是否希望任何错误处理覆盖可能的意外情况,这是您的决定。还请注意,这将允许您对包含许多行的输入同时执行此操作

正如BrianM.Sheldon所说,如果您正在寻找的是在末尾查找的东西,那么使用string split()(或rsplit())也会在适当的时候“Pythonic”,这看起来如下:

foo = "John Smith --- 1234567"

bar = [str(s) for s in foo.split() if s.isdigit()]
>>> data = "John Smith --- 1234567"
>>> idtext = data.rsplit(' --- ', 1)[1]
>>> int(idtext)
1234567

我首先展示了regex版本,因为根据我的经验,在一行上执行此操作可能意味着您有一堆行,从一行到使用re.findall()使这比手动迭代行(使用for循环或生成器等)要简单一些并将拆分应用于每个表达式。

正则表达式的适当用法是“Pythonic”:

正则表达式要求输入任何序列,后跟“--”标记,后跟数字,然后是行尾。这可能限制太多,或者限制不够,具体取决于实际数据

这是否适合您的情况,以及您是否希望任何错误处理覆盖可能的意外情况,这是您的决定。还请注意,这将允许您对包含许多行的输入同时执行此操作

正如Brian M.Sheldon所评论的,使用字符串split()(或者rsplit(),如果您在末尾查找某个内容的话)在适当的时候也是“Pythonic”的,这看起来像这样:

foo = "John Smith --- 1234567"

bar = [str(s) for s in foo.split() if s.isdigit()]
>>> data = "John Smith --- 1234567"
>>> idtext = data.rsplit(' --- ', 1)[1]
>>> int(idtext)
1234567

我首先展示了regex版本,因为根据我的经验,在一行上执行此操作可能意味着您有一堆行,从一行到使用re.findall()使这比手动迭代行(使用for循环或生成器等)要简单一些并将拆分应用于每个对象。

您可以使用
过滤器
str.isdigit

''.join(list(filter(str.isdigit, foo)))

您可以使用
filter
str.isdigit

''.join(list(filter(str.isdigit, foo)))

如果我正确理解你的问题…:

id = int(foo.split(' --- ')[-1])

首先,您的
foo
被分成一个列表两部分-在
--
之前和之后-然后此列表的最后一个元素(显然应该是ID)被转换为int。

如果我正确理解了您的问题…:

id = int(foo.split(' --- ')[-1])

首先,您的
foo
被分成一个列表两部分-在
--
之前和之后-然后此列表的最后一个元素(显然应该是ID)被转换为int.

bar=[int(s[-1]),用于foo.split()中的s
@Michael,而不是在实际的分隔符
foo.split(--)或
bar=[int(s)上拆分[-1])对于foo.split()]中的s
@Michael改为使用实际分隔符
foo.split(“--”)进行拆分,虽然我同意适当的正则表达式是pythonic的,但如果文本的格式与前面提到的一致,则在
上进行拆分“---”
获取最后一个值是pythonic的,而且比正则表达式更快。此外,这个正则表达式可能会得到改进,它至少需要18个步骤才能获得1位数的ID,24个步骤才能获得7位数的ID,如示例所示。相比之下,
“--(\d+)$”
无论ID长度如何,只需要9个步骤。@Brian,re.match()例程被锚定到文本的开头。若要删除。*部分,需要使用re.search()相反。非常正确,但我发现自己使用
re.search
的频率比使用
re.match
的频率要高,除非模式真的在字符串的开头。@Brian,这是完全合理的。就我而言,我喜欢非常明确地说明我实际上跳过了什么,即使它只是“任何东西”。我认为它使我的代码更具可读性。虽然我同意适当的正则表达式是pythonic,但如果文本的格式与前面提到的一致,则在
上拆分--”
获取最后一个值是pythonic的,而且比正则表达式更快。此外,这个正则表达式可能会得到改进,它至少需要18个步骤才能获得1位数的ID,24个步骤才能获得7位数的ID,如示例所示。相比之下,
“--(\d+)$”
无论ID长度如何,只需要9个步骤。@Brian,re.match()例程被锚定到文本的开头。若要删除。*部分,需要使用re.search()相反。非常正确,但我发现自己使用
re.search
的频率比使用
re.match
的频率要高,除非模式真的在字符串的开头。@Brian,这是完全合理的。就我而言,我喜欢非常明确地说明我实际上跳过了什么,即使它只是“任何东西”。我认为这会使我的代码更具可读性。在我看来,这是一种高压方法。我认为在分隔符上拆分是更好的选择。在我看来,这是一种高压方法。我认为在分隔符上拆分是更好的选择。这是我认为最好的答案,但您可能应该解释代码的实际用途这是我认为最好的答案,