如何可靠地在Python中分割string?

在Perl中,我可以这样做:

my ($x, $y) = split /:/, $str; 

不pipestring是否包含模式,它都会起作用。

在Python中,但是这不起作用:

 a, b = "foo".split(":") # ValueError: not enough values to unpack 

在这种情况下防止错误的规范方法是什么?

如果你分裂成两部分(就像你的例子),你可以使用str.partition()来获得一个保证参数的解包大小为3:

 >>> a, sep, b = "foo".partition(":") >>> a, sep, b ('foo', '', '') 

str.partition()总是返回一个3元组,无论是否find分隔符。

Python 3的另一个替代方法是使用扩展解包,如@ cdarke的答案中所述 :

 >>> a, *b = "foo".split(":") >>> a, b ('foo', []) 

这将第一个拆分项分配给a ,剩余项目列表(如果有的话)分配给b

既然你是在Python 3,那很简单。 PEP 3132引入了对赋值给元组的语法的一个受欢迎的简化 – 扩展的迭代解包 。 过去,如果赋值给一个元组中的variables,赋值左边的项目数量必须与右边的项目数量完全相同。

在Python 3中,我们可以用星号*作为前缀来将左侧的任何variables指定为列表。 这将尽可能多地获取值,同时仍然将variables填充到右侧(所以它不一定是最右边的项目)。 当我们不知道元组的长度时,这避免了许多令人讨厌的切片。

 a, *b = "foo".split(":") print("a:", a, "b:", b) 

得到:

 a: foo b: [] 

编辑下面的评论和讨论:

与Perl版本相比,这是相当不同的,但它是Python(3)的方式。 与Perl版本相比, re.split()会更相似,但是调用RE引擎来分割单个字符是不必要的开销。

在Python中有多个元素:

 s = 'hello:world:sailor' a, *b = s.split(":") print("a:", a, "b:", b) 

得到:

 a: hello b: ['world', 'sailor'] 

但是在Perl中:

 my $s = 'hello:world:sailor'; my ($a, $b) = split /:/, $s; print "a: $ab: $b\n"; 

得到:

 a: hello b: world 

可以看出,在Perl中,其他元素被忽略或丢失。 如果需要,在Python中复制相当容易:

 s = 'hello:world:sailor' a, *b = s.split(":") b = b[0] print("a:", a, "b:", b) 

所以,在Perl中, a, *b = s.split(":")等价的

 my ($a, @b) = split /:/, $s; 

注意:我们不应该在普通Perl中使用$a$b ,因为它们在sort时有特殊的含义。 为了与Python示例保持一致,我在这里使用了它们。

Python确实有一个额外的技巧,我们可以解开左侧元组中的任何元素:

 s = "one:two:three:four" a, *b, c = s.split(':') print("a:", a, "b:", b, "c:", c) 

得到:

 a: one b: ['two', 'three'] c: four 

而在Perl中,数组( @b )是贪婪的,而标量$cundef

 use strict; use warnings; my $s = 'one:two:three:four'; my ($a, @b, $c) = split /:/, $s; print "a: $ab: @bc: $c\n"; 

得到:

 Use of uninitialized value $c in concatenation (.) or string at gash.pl line 8. a: one b: two three four c: 

你总是可以自由地发现exception。

例如:

 some_string = "foo" try: a, b = some_string.split(":") except ValueError: a = some_string b = "" 

如果将整个原始string分配给a ,将空string分配给b是所需的行为,那么我可能会使用str.partition()作为eugene y的build议。 但是,这种解决scheme可以让您更精确地控制string中没有分隔符时发生的情况,这在某些情况下可能会有用。

split总是会返回一个列表。 a, b = ...总是期望列表长度是两个。 你可以使用像l = string.split(':'); a = l[0]; ... l = string.split(':'); a = l[0]; ... l = string.split(':'); a = l[0]; ...

这里是一个单行: a, b = (string.split(':') + [None]*2)[:2]

如何使用正则expression式:

 import re string = 'one:two:three:four' 

在3.X中:

 a, *b = re.split(':', string) 

在2.X:

 a, b = re.split(':', string)[0], re.split(':', string)[1:] 

这样你也可以使用正则expression式来分割(即\ d)