截断字符串而不在单词中间结束

python truncate 匿名 | 2020-02-27 02:21:34


我正在寻找一种在Python中截断字符串的方法,这种方法不会在单词中间截断字符串。
例如:
Original:“这真是太棒了。”
“Dumb”truncate:“这是真的…”
“Smart”truncate:“这真的…”
我正在寻找一种从上面完成“Smart”截断的方法。





7 答案



实际上,我在最近的一个项目中为此写了一个解决方案。我已经将大部分内容压缩为更小的一点。
def smart_truncate(content, length=100, suffix='...'):
if len(content) <= length:
return content
else:
return ' '.join(content[:length+1].split(' ')[0:-1]) + suffix

发生的是if语句检查您的内容是否已经小于截止点。如果不是,它会截断到所需的长度,在空格上拆分,删除最后一个元素(这样就不会切掉一个单词),然后将其重新连接起来(同时附加“…”)。

2020-02-27 02:21:52
匿名


下面是Adam解决方案最后一行的一个稍好的版本:
return content[:length].rsplit(' ', 1)[0]+suffix

(这稍微更有效,如果字符串前面没有空格,则返回更合理的结果。)

2020-02-27 02:22:12
匿名


有一些可能对您有问题,也可能没有问题,例如处理制表符(例如,如果您将制表符显示为8个空格,但在内部将其视为1个字符)、处理各种类型的断开和不断开空白,或者允许断开连字符等等(如果需要的话),您可能想看看textwrap模块。例如:
def truncate(text, max_size):
if len(text) <= max_size:
return text
return textwrap.wrap(text, max_size-3)[0] + "..."

大于max_size的单词的默认行为是打断它们(使max_size成为硬限制)。通过将break_long_words=False传递给wrap(),可以更改为其他一些解决方案使用的软限制,在这种情况下,它将返回整个单词。如果您希望此行为,请将最后一行更改为:
    lines = textwrap.wrap(text, max_size-3, break_long_words=False)
return lines[0] + ("..." if len(lines)>1 else "")

根据您希望的具体行为,还有一些其他选项(如展开选项卡)可能会引起兴趣。

2020-02-27 02:22:30
匿名


def smart_truncate1(text, max_length=100, suffix='...'):
"""Returns a string of at most `max_length` characters, cutting
only at word-boundaries. If the string was truncated, `suffix`
will be appended.
"""
if len(text) > max_length:
pattern = r'^(.{0,%d}\S)\s.*' % (max_length-len(suffix)-1)
return re.sub(pattern, r'\1' + suffix, text)
else:
return text
/code>


def smart_truncate2(text, min_length=100, suffix='...'):
"""If the `text` is more than `min_length` characters long,
it will be cut at the next word-boundary and `suffix`will
be appended.
"""
pattern = r'^(.{%d,}?\S)\s.*' % (min_length-1)
return re.sub(pattern, r'\1' + suffix, text)

def smart_truncate3(text, length=100, suffix='...'):
"""Truncates `text`, on a word boundary, as close to
the target length it can come.
"""
slen = len(suffix)
pattern = r'^(.{0,%d}\S)\s+\S+' % (length-slen-1)
if len(text) > length:
match = re.match(pattern, text)
if match:
length0 = match.end(0)
length1 = match.end(1)
if abs(length0+slen-length) < abs(length1+slen-length):
return match.group(0) + suffix
else:
return match.group(1) + suffix
return text

2020-02-27 02:23:00
匿名


>>> import textwrap
>>> textwrap.wrap('The quick brown fox jumps over the lazy dog', 12)
['The quick', 'brown fox', 'jumps over', 'the lazy dog']

你只需取第一个元素,就完成了…

2020-02-27 02:23:16
匿名


def smart_truncate(s, width):
if s[width].isspace():
return s[0:width];
else:
return s[0:width].rsplit(None, 1)[0]

测试:
>>> smart_truncate('The quick brown fox jumped over the lazy dog.', 23) + "..."
'The quick brown fox...'

2020-02-27 02:23:31
匿名


在Python3.4+中,您可以使用textwrap.shorten。在OP示例中:
>>> import textwrap
>>> original = "This is really awesome."
>>> textwrap.shorten(original, width=20, placeholder="...")
'This is really...'

textwrap.shorten(text,width,**kwargs)
折叠并截断给定的文本以适合给定的宽度。
首先折叠文本中的空白(所有空白都用单个空格替换)。如果结果符合宽度,则返回
。否则,将从结尾删除足够的单词,以便
剩余单词加上占位符适合宽度:

2020-02-27 02:23:50
匿名


World is powered by solitude
备案号:湘ICP备19012068号