Вставьте символ новой строки каждые 64 символа, используя Python - PullRequest
23 голосов
/ 17 апреля 2010

При использовании Python мне нужно вставлять символ новой строки в строку каждые 64 символа. В Perl это просто:

s/(.{64})/$1\n/

Как это можно сделать с помощью регулярных выражений в Python? Есть ли более питонический способ сделать это?

Ответы [ 7 ]

30 голосов
/ 17 апреля 2010

То же, что и в Perl, но с обратным слешем вместо доллара для доступа к группам:

s = "0123456789"*100 # test string
import re
print re.sub("(.{64})", "\\1\n", s, 0, re.DOTALL)

re.DOTALL является эквивалентом опции Perl s/.

23 голосов
/ 17 апреля 2010

без регулярных выражений:

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))
13 голосов
/ 17 апреля 2010

Я бы пошел с:

import textwrap
s = "0123456789"*100
print '\n'.join(textwrap.wrap(s, 64))
8 голосов
/ 17 апреля 2010

принимая @ J.F. Решение Себастьяна на шаг впереди, и это почти преступник: -)

import textwrap
s = "0123456789"*100
print textwrap.fill(s, 64)

смотри, ма ... без регулярных выражений! потому что, как вы знаете ... http://regex.info/blog/2006-09-15/247

спасибо за то, что познакомили нас с модулем textwrap ... хотя он был в Python с 2.3, я никогда не знал об этом до сих пор (да, я признаю это публично)! !

4 голосов
/ 17 апреля 2010

Крошка, не приятно:

"".join(s[i:i+64] + "\n" for i in xrange(0,len(s),64))
3 голосов
/ 17 апреля 2010

Я предлагаю следующий метод:

"\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

2-ая Герни Алекса / метод Майкла:

$ 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 правильным для спецификации вопроса, поэтому я не буду его оценивать.

EDIT

Изменен ответ, потому что он был неправильным (позор мне!)

РЕДАКТИРОВАТЬ 2

Просто для удовольствия, метод RE-free с использованием itertools. По скорости он занимает третье место, и это не Pythonic (слишком шумно):

"\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
1 голос
/ 31 июля 2015

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...