Разделение только длинных слов в строке

У меня есть случайная строка, скажем:

s = "This string has some verylongwordsneededtosplit"

Я пытаюсь написать функцию trunc_string (string, len), которая принимает строку в качестве аргумента для работы и «len» в качестве количества символов после длинных слов, которые будут разделены.

Результат должен быть примерно таким

str = trunc_string(s, 10)
str = "This string has some verylongwo rdsneededt osplit"

А пока у меня есть что-то вроде этого:

def truncate_long_words(s, num):
"""Splits long words in string"""
words = s.split()
for word in words:
    if len(word) > num:
        split_words = list(words)

После этой части у меня есть это длинное слово в виде списка символов. Теперь мне нужно:

  • объединить символы 'num' вместе во временный список word_part
  • объединить все word_parts в одно слово
  • соедините это слово с остальными словами, которые не были достаточно длинными, чтобы их можно было разделить.

Должен ли я сделать это как-то похожим образом? :

counter = 0
for char in split_words:
    word_part.append(char)
    counter = counter+1
    if counter == num

И тут надо как-то соединить все word_part вместе, создав слово и дальше


person sasklacz    schedule 17.03.2010    source источник
comment
Почему бы не использовать регулярное выражение для определения длинных слов. Например, это регулярное выражение будет соответствовать любым словам, состоящим из более чем 10 последовательных символов без пробелов и менее 1000 последовательных символов без пробелов: [^ \ s] {10,1000}   -  person Lonnie Best    schedule 17.03.2010
comment
Это для переноса слов? Если это так, вы можете использовать библиотеку расстановки переносов, которая будет намного более разумной в отношении того, где она выбирает разделение слов.   -  person Daniel Stutzbach    schedule 17.03.2010


Ответы (4)


Почему нет:

  def truncate_long_words(s, num):
     """Splits long words in string"""
     words = s.split()
     for word in words:
        if len(word) > num:
                for i in xrange(0,len(word),num):
                       yield word[i:i+num]
        else:
            yield word

 for t in truncate_long_words(s):
    print t
person Alexander Gessler    schedule 17.03.2010

def split_word(word, length=10):
    return (word[n:n+length] for n in range(0, len(word), length))

string = "This string has some verylongwordsneededtosplit"

print [item for word in string.split() for item in split_word(word)]
# ['This', 'string', 'has', 'some', 'verylongwo', 'rdsneededt', 'osplit']

Примечание: называть строку str - плохая идея. Он затеняет встроенный шрифт.

person Matt Anderson    schedule 17.03.2010
comment
очень чистое решение, оно мне очень нравится. - person Adrien Plisson; 17.03.2010

вариант - модуль текстового переноса
http://docs.python.org/2/library/textwrap.html

пример использования:

>>> import textwrap
>>> s = "This string has some verylongwordsneededtosplit"
>>> list = textwrap.wrap(s, width=10)
>>> for line in list: print line;
... 
This
string has
some veryl
ongwordsne
ededtospli
t
>>>
person Walter Renner    schedule 30.10.2012

Злоупотребление регулярным выражением:

import re
def trunc_string(s, num):
   re.sub("(\\w{%d}\\B)" % num, "\\1 ", s)

assert "This string has some verylongwo rdsneededt osplit" == trunc_string("This string has some verylongwordsneededtosplit", 10)

(Правка: принято упрощение Брайаном. Спасибо. Но я оставил \B, чтобы не добавлять пробел, когда слово имеет длину ровно 10 символов.)

person kennytm    schedule 17.03.2010
comment
Проще: return re.sub ('([a-zA-Z] {% d})'% num, '\\ 1', s) - person Brian; 17.03.2010