Использование Python Мне нужно вставить символ новой строки в строку каждые 64 символа. В Perl это легко:
s/(.{64})/$1\n/
Как это можно сделать с помощью регулярных выражений в Python? Есть ли более питонический способ сделать это?
Использование Python Мне нужно вставить символ новой строки в строку каждые 64 символа. В Perl это легко:
s/(.{64})/$1\n/
Как это можно сделать с помощью регулярных выражений в Python? Есть ли более питонический способ сделать это?
То же, что и в Perl, но с обратной косой чертой вместо доллара для доступа к группам:
s = "0123456789"*100 # test string
import re
print re.sub("(.{64})", "\\1\n", s, 0, re.DOTALL)
re.DOTALL
является эквивалентом опции Perl s/
.
без regexp:
def insert_newlines(string, every=64):
lines = []
for i in xrange(0, len(string), every):
lines.append(string[i:i+every])
return '\n'.join(lines)
более короткий, но менее читаемый (imo):
def insert_newlines(string, every=64):
return '\n'.join(string[i:i+every] for i in xrange(0, len(string), every))
Код выше для Python 2.x. Для Python 3.x вы хотите использовать range
, а не xrange
:
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))
Я бы пошел с:
import textwrap
s = "0123456789"*100
print '\n'.join(textwrap.wrap(s, 64))
взятие @J.F. Решение Себастьяна на один шаг дальше, и это почти преступно: -)
import textwrap
s = "0123456789"*100
print textwrap.fill(s, 64)
Посмотрите ма... нет регулярных выражений! потому что, как вы знаете... http://regex.info/blog/2006-09-15/247
спасибо за то, что вы познакомили нас с textwrap
module... хотя он был с Python с 2.3, я никогда не знал об этом до сих пор (да, я признаю это публично)!!
Маленький, не очень приятный:
"".join(s[i:i+64] + "\n" for i in xrange(0,len(s),64))
Предлагаю следующий метод:
"\n".join(re.findall("(?s).{,64}", s))[:-1]
Это более или менее метод non-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
gurney alex 2nd/Michael метод:
$ 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
правильным для спецификации вопроса, поэтому я не буду его время.
Изменен ответ, потому что он был неправильным (стыдно за меня!)
Просто для удовольствия, метод RE-free с использованием itertools
. Он занимает третье место по скорости, и это не Pythonic (слишком lispy):
"\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
itertools имеет приятный рецепт для функции grouper
, которая хороша для этого, особенно если ваш последний фрагмент меньше 64 символов, и вы не хотите ошибки среза:
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))