2009-10-01 105 views

回答

3

这将是一个简洁的方式:

import re 

s = "aa67bc54c9" 
print ''.join(t * int(n) for t, n in re.findall(r"([a-z]+)([0-9]+)", s)) 

该解决方案使用正则表达式匹配“一个或多个字母后跟一个或多个数字”,寻找在所有这些输入字符串。然后它使用列表理解遍历每个找到的组,并依次将字母分配给tn。该列表使用字符串*运算符生成字符串,该运算符将字符串重复给定次数(使用int()将数字字符串转换为整数)。最后,使用''.join()将所有内容粘贴在一起。

对于正则表达式,[a-z]是由任何单个(小写)字母组成的字符类。 [a-z]+表示一个或多个小写字母。同样,[0-9]+表示一个或多个数字。每个组件周围的分组括号会“捕捉”其中的字符,并使其可用作为findall()函数的结果。有两组圆括号,所以有两个输出值,它们在列表理解中被分配到tn

+0

非常感谢你的回答,你可以请exaplin正则表达式([a-z] +)([0-9] +) – Edwards 2009-10-01 03:56:32

+0

如果StackOverflow对我没有下降,完全会击败你。但我会给它一点空间。 – 2009-10-01 03:56:54

+0

为了理解正则表达式,首先阅读我的答案。有关Python中正则表达式的完整说明,请参阅以下教程:http://www.amk.ca/python/howto/regex/ – steveha 2009-10-01 06:08:06

3

这是我的Python解决方案。

import re 
pat = re.compile("^(\D+)(\d+)(.*)$") 

def rle_expand(s): 
    lst = [] 
    while True: 
     m = pat.match(s) 
     if m: 
      n = int(m.group(2)) 
      lst.append(m.group(1) * n) 
     else: 
      lst.append(s) 
      break 
     s = m.group(3) 
    return "".join(lst) 

s = "aa03bc05d9whew" 

print rle_expand(s) 
# prints aaaaaabcbcbcbcbcdddddddddwhew 

s = “aa67bc54c9” 
print rle_expand(s) 
# prints: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcccccccccc 

问题基本上是扩展一个游程编码。首先你有某种模式,然后是一些数字,指定重复模式的次数。

首先我们导入re模块,以访问Python的正则表达式。

接下来我们编译一次模式,以便稍后使用它。这种模式会做什么?

该模式使用圆括号标记匹配字符串中的字母组。有三对parens,所以这将匹配三组。在第一组是一个'^'字符之前,它锚定到字符串的开头,并且在最后一组之后是一个'$'字符,它锚定在字符串的末尾;在这种情况下,这些并不是绝对必要的。第一组匹配使用特殊序列而不是的任何数字\D; +扩展它以匹配一个或多个非数字实例的运行。第二组类似,使用\d+来匹配一个或多个数字的运行。第三组使用.来匹配任何字符,然后用*扩展它以匹配任意字符的0或更多的运行。 (注意:*+非常相似,它只是*匹配0个或更多的东西,+匹配一个或多个)。

使用标准的Python的成语,我们建立使用列表的字符串。我们从一个空的列表开始(称为lst)。只要模式保持匹配的东西,我们将东西附加到这个列表中。当我们完成后,我们使用"".join()将列表一起加入到一个字符串中。

pat.match()返回一个名为“匹配对象”的对象,或者如果匹配失败,返回None。如果匹配成功,我们将匹配组2转换为整数,并在匹配组1上使用Python字符串重复运算符(“multiply”)进行运行长度扩展。在此之后,我们用匹配组3的结果重新命名s的名称,从而截断刚刚处理的字符串部分,并循环。如果匹配失败,我们只需将所有s附加到列表中并跳出循环。

建立一个列表,然后在列表上使用"".join()是一个标准的Python成语。它可以在任何版本的Python下都有良好的性能。因为Python字符串是不可变的,所以如果通过重复附加到字符串来建立长动态字符串,性能可能会非常慢;在创建最终字符串时,您会多次复制字符串的早期部分。 Python列表可以简单地附加到,然后最后的连接操作非常快。 (Python的最新版本已经优化了你反复附加到一个字符串的情况,并且不再遭受这种情况下的重复复制。)

Greg Hewgill的解决方案只识别从'a'到'z的小写字母'为扩展文本;你可以通过把\D而不是[a-z]来解决这个问题。他的解决方案使用明确的范围,如[0-9],其中我的解决方案使用Python简写缩写(如\d)。他的解决方案只扩展了游程编码序列;如果有一个尾部序列没有整数,那么我的这个序列不变,而他默默地忽略它。但是,必须说他的解决方案非常优雅,我希望我能想到它。 :-)

+0

Stevha非常感谢您的优雅解释以及扩展的正则表达式。希望stackoverflow允许我选择更多,然后诚实地回答这个使用列表来获得我想要的是第一个想到的解决方案。 – Edwards 2009-10-01 07:38:55