使用Python,我需要每64个字符插入一个换行符到字符串中。在Perl中,这很简单:
s/(.{64})/$1\n/
如何使用Python中的正则表达式来实现这一点?有没有更pythonic的方法来做这件事?
js5cn81o1#
与Perl中相同,但使用反斜杠而不是美元来访问组:
s = "0123456789"*100 # test string import re print re.sub("(.{64})", "\\1\n", s, 0, re.DOTALL)
re.DOTALL相当于Perl的s/选项。
re.DOTALL
s/
o4tp2gmn2#
没有regexp:
def insert_newlines(string, every=64): lines = [] for i in range(0, len(string), every): lines.append(string[i:i+every]) return '\n'.join(lines)
较短但可读性较差(海事组织):
def insert_newlines(string, every=64): return '\n'.join(string[i:i+every] for i in range(0, len(string), every))
(For Python 2,使用xrange而不是range。
xrange
range
jm81lzqq3#
我会说:
import textwrap s = "0123456789"*100 print('\n'.join(textwrap.wrap(s, 64)))
mccptt674#
@J.F.塞巴斯蒂安的solution更进一步(这是 * 几乎 * 犯罪!:-)):
:-)
import textwrap s = "0123456789"*100 print textwrap.fill(s, 64)
听着妈...没有正则表达式!因为你也知道http://regex.info/blog/2006-09-15/247感谢您为我们介绍textwrap模块.虽然它从Python 2.3开始就存在了,但我直到现在才意识到它(是的,我必须承认这一点)!!
textwrap
bxgwgixi5#
很小,不好:
"".join(s[i:i+64] + "\n" for i in xrange(0,len(s),64))
z9smfwbn6#
我建议采用以下方法:
"\n".join(re.findall("(?s).{,64}", s))[:-1]
这或多或少是一种利用RE引擎进行循环的非RE方法。在一个非常慢的计算机上,我有一个家庭服务器,这给:
$ python -m timeit -s 's="0123456789"*100; import re' '"\n".join(re.findall("(?s).{,64}", s))[:-1]' 10000 loops, best of 3: 130 usec per loop
AndiDog的方法:
$ python -m timeit -s "s='0123456789'*100; import re" 're.sub("(?s)(.{64})", r"\1\n", s)' 1000 loops, best of 3: 800 usec per loop
格尼·亚历克斯第二法/迈克尔法:
$ python -m timeit -s "s='0123456789'*100" '"\n".join(s[i:i+64] for i in xrange(0, len(s), 64))' 10000 loops, best of 3: 148 usec per loop
我不认为textwrap方法对于问题的规范是正确的,所以我不会计时。
改变答案,因为它是不正确的(我的耻辱!)
只是为了好玩,使用itertools的无RE方法。它在速度上排名第三,而且它不是Pythonic(太清晰):
itertools
"\n".join( it.imap( s.__getitem__, it.imap( slice, xrange(0, len(s), 64), xrange(64, len(s)+1, 64) ) ) ) $ python -m timeit -s 's="0123456789"*100; import itertools as it' '"\n".join(it.imap(s.__getitem__, it.imap(slice, xrange(0, len(s), 64), xrange(64, len(s)+1, 64))))' 10000 loops, best of 3: 182 usec per loop
dl5txlt97#
itertools有一个很好的函数grouper,特别是如果你的最终切片小于64个字符,并且你不希望出现切片错误:
grouper
def grouper(iterable, n, fillvalue=None): "Collect data into fixed-length chunks or blocks" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx args = [iter(iterable)] * n return izip_longest(fillvalue=fillvalue, *args)
像这样使用:
big_string = <YOUR BIG STRING> output = '\n'.join(''.join(chunk) for chunk in grouper(big_string, 64))
7条答案
按热度按时间js5cn81o1#
与Perl中相同,但使用反斜杠而不是美元来访问组:
re.DOTALL
相当于Perl的s/
选项。o4tp2gmn2#
没有regexp:
较短但可读性较差(海事组织):
(For Python 2,使用
xrange
而不是range
。jm81lzqq3#
我会说:
mccptt674#
@J.F.塞巴斯蒂安的solution更进一步(这是 * 几乎 * 犯罪!
:-)
):听着妈...没有正则表达式!因为你也知道http://regex.info/blog/2006-09-15/247
感谢您为我们介绍
textwrap
模块.虽然它从Python 2.3开始就存在了,但我直到现在才意识到它(是的,我必须承认这一点)!!bxgwgixi5#
很小,不好:
z9smfwbn6#
我建议采用以下方法:
这或多或少是一种利用RE引擎进行循环的非RE方法。
在一个非常慢的计算机上,我有一个家庭服务器,这给:
AndiDog的方法:
格尼·亚历克斯第二法/迈克尔法:
我不认为
textwrap
方法对于问题的规范是正确的,所以我不会计时。编辑
改变答案,因为它是不正确的(我的耻辱!)
编辑2
只是为了好玩,使用
itertools
的无RE方法。它在速度上排名第三,而且它不是Pythonic(太清晰):dl5txlt97#
itertools有一个很好的函数
grouper
,特别是如果你的最终切片小于64个字符,并且你不希望出现切片错误:像这样使用: