用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'