Python 如何从格式一致的字符串列表中提取ID号
我正在处理一组数据,这些数据的名称和用户名组合在一个字符串中。例如,如果用户名为“John Smith”,其ID号为1234567,则字符串将为“John Smith---1234567”。字符串的格式一致,始终为: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(
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,这是完全合理的。就我而言,我喜欢非常明确地说明我实际上跳过了什么,即使它只是“任何东西”。我认为这会使我的代码更具可读性。在我看来,这是一种高压方法。我认为在分隔符上拆分是更好的选择。在我看来,这是一种高压方法。我认为在分隔符上拆分是更好的选择。这是我认为最好的答案,但您可能应该解释代码的实际用途这是我认为最好的答案,