用Python以特定模式打印字母
我有下面的字符串并将其拆分:用Python以特定模式打印字母,python,regex,string,Python,Regex,String,我有下面的字符串并将其拆分: >>> st = '%2g%k%3p' >>> l = filter(None, st.split('%')) >>> print l ['2g', 'k', '3p'] 现在我想把g字母打印两次,k字母打印一次,p字母打印三次: ggkppp 这是怎么可能的?您可以使用generator和isdigit()检查您的第一个符号是否为数字,然后返回具有适当计数的以下字符串。然后您可以使用join获取输出: ''
>>> st = '%2g%k%3p'
>>> l = filter(None, st.split('%'))
>>> print l
['2g', 'k', '3p']
现在我想把g字母打印两次,k字母打印一次,p字母打印三次:
ggkppp
这是怎么可能的?您可以使用
generator
和isdigit()
检查您的第一个符号是否为数字,然后返回具有适当计数的以下字符串。然后您可以使用join
获取输出:
''.join(i[1:]*int(i[0]) if i[0].isdigit() else i for i in l)
演示:
In [70]: [i[1:]*int(i[0]) if i[0].isdigit() else i for i in l ]
Out[70]: ['gg', 'k', 'ppp']
In [71]: ''.join(i[1:]*int(i[0]) if i[0].isdigit() else i for i in l)
Out[71]: 'ggkppp'
编辑
当第一个数字包含多个数字时,使用re
模块:
''.join(re.search('(\d+)(\w+)', i).group(2)*int(re.search('(\d+)(\w+)', i).group(1)) if re.search('(\d+)(\w+)', i) else i for i in l)
例如:
In [144]: l = ['12g', '2kd', 'h', '3p']
In [145]: ''.join(re.search('(\d+)(\w+)', i).group(2)*int(re.search('(\d+)(\w+)', i).group(1)) if re.search('(\d+)(\w+)', i) else i for i in l)
Out[145]: 'ggggggggggggkdkdhppp'
EDIT2
对于您的输入,例如:
st = '%2g_%3k%3p'
如果列表末尾的工作带有
符号,则可以将
替换为空字符串,然后将
添加到末尾:
st = '%2g_%3k%3p'
l = list(filter(None, st.split('%')))
''.join((re.search('(\d+)(\w+)', i).group(2)*int(re.search('(\d+)(\w+)', i).group(1))).replace("_", "") + '_' * i.endswith('_') if re.search('(\d+)(\w+)', i) else i for i in l)
输出:
'gg_kkkppp'
EDIT3
不带re
模块的解决方案,但通常循环工作2位。您可以定义函数:
def add_str(ind, st):
if not st.endswith('_'):
return st[ind:] * int(st[:ind])
else:
return st[ind:-1] * int(st[:ind]) + '_'
def collect(l):
final_str = ''
for i in l:
if i[0].isdigit():
if i[1].isdigit():
final_str += add_str(2, i)
else:
final_str += add_str(1, i)
else:
final_str += i
return final_str
然后将其用作:
l = ['12g_', '3k', '3p']
print(collect(l))
gggggggggggg_kkkppp
循环列表,检查第一个条目中的数字,然后将第二个数字加在后面:
string=''
l = ['2g', 'k', '3p']
for entry in l:
if len(entry) ==1:
string += (entry)
else:
number = int(entry[0])
for i in range(number):
string += (entry[1:])
单行正则表达式方式:
>>> import re
>>> st = '%2g%k%3p'
>>> re.sub(r'%|(\d*)(\w+)', lambda m: int(m.group(1))*m.group(2) if m.group(1) else m.group(2), st)
'ggkppp'
%|(\d*)(\w+)
正则表达式匹配所有%
并将任何单词字符前的零位或多位数字捕获到一个组中,并将以下单词字符捕获到另一个组中。更换时,应按照更换零件中给出的值更换所有匹配的字符。所以这应该是松散的%
字符
或
假设您总是打印单个字母,但前面的数字可能比以10为基数的单个数字长
seq = ['2g', 'k', '3p']
result = ''.join(int(s[:-1] or 1) * s[-1] for s in seq)
assert result == "ggkppp"
演出迟到了,但准备出发了
另一种方法是定义将nC转换为CCCC…C(ntimes)的函数,然后将其传递给映射
,将其应用于列表l
中的每个元素,该元素来自拆分%
,最后将它们全部合并,如下所示:
>>> def f(s):
x = 0
if s:
if len(s) == 1:
out = s
else:
for i in s:
if i.isdigit():
x = x*10 + int(i)
out = x*s[-1]
else:
out = ''
return out
>>> st
'%4g%10k%p'
>>> ''.join(map(f, st.split('%')))
'ggggkkkkkkkkkkp'
>>> st = '%2g%k%3p'
>>> ''.join(map(f, st.split('%')))
'ggkppp'
或者,如果您想将所有这些放在一个函数定义中:
>>> def f(s):
out = ''
if s:
l = filter(None, s.split('%'))
for item in l:
x = 0
if len(item) == 1:
repl = item
else:
for c in item:
if c.isdigit():
x = x*10 + int(c)
repl = x*item[-1]
out += repl
return out
>>> st
'%2g%k%3p'
>>> f(st)
'ggkppp'
>>>
>>> st = '%4g%10k%p'
>>>
>>> f(st)
'ggggkkkkkkkkkkp'
>>> st = '%4g%101k%2p'
>>> f(st)
'ggggkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkpp'
>>> len(f(st))
107
编辑:
如果OP不希望重复此字符,那么我认为最好的方法是使用。
,这样会使事情变得更简单:
>>> def f(s):
pat = re.compile(r'%(\d*)([a-zA-Z]+)')
out = pat.sub(lambda m:int(m.group(1))*m.group(2) if m.group(1) else m.group(2), s)
return out
>>> st = '%4g_%12k%p__%m'
>>> f(st)
'gggg_kkkkkkkkkkkkp__m'
当一个字母超过9个时会发生什么情况?'.join(i[1:]*int(i[0]),如果i[0]。isdigit()否则i代表[12g',k',3p'])
='2GKPP'
@Anton。想象:st='%2g\uU%3k%3p'
因此结果是:'g\u KKKPP'
但我想要这个结果:'gg\u KKKKPP'
@MLSC您是否只需要\uUKKKPP>符号的行为?@MLSC尝试编辑版本。你可以把它扩展到你喜欢的地方。这是来自html代码吗?字母前的数字会超过一位数吗?这个数字会是零吗?@Irano不,这不是。@PM是的,它可能超过一个数字……你需要一个更正式的输入语言规范。%
的确切含义是什么,数字的哪些值是有效的,以及“要打印的字符串”的哪些值是有效的?例如,%234
是什么意思?它的意思是“打印34
两次”,还是因为后面没有字母而无效,或者是其他什么?那%55a5
呢?打印a5
55次,或者打印5a5
5次,或者打印5
5次,然后打印a5
?有很多情况你没有在这里指定。你能解释一下为什么你使用\b
?…因为我认为它没有必要吗?测试:re.sub(r%(\d*)(\w*),'-re-',st)
->'-re--re--re-'
仅用于小写字母r%(\d*)([a-z]+)'
或作为一行程序:result='.join([int(s[-1]或[-1]对于st.split(“%”)中的s,如果s])
。您可以给.join
一个生成器表达式,但实际上给它一个列表comp更有效.join
必须解析其输入两次:第一次传递决定输出字符串的大小,第二次传递生成输出。因此,如果给.join
一个gen exp,它必须运行生成器并从中构建一个列表,然后才能开始实际的连接。string
不是一个很好的变量名,因为它是标准Python模块的名称。另外,如果一个数字超过1位,这个答案也不能正常工作。@MLSC…在这种情况下,您的预期输出是什么gg_kkkkkkkkkkkkkkkkppp
?请原谅我的意思:但如果我说st=%2g_kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk。。没有pblm:)
>>> def f(s):
pat = re.compile(r'%(\d*)([a-zA-Z]+)')
out = pat.sub(lambda m:int(m.group(1))*m.group(2) if m.group(1) else m.group(2), s)
return out
>>> st = '%4g_%12k%p__%m'
>>> f(st)
'gggg_kkkkkkkkkkkkp__m'