Python截断长字符串


244

如何在Python中将字符串截断为75个字符?

这是在JavaScript中完成的方式:

var data="saddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
var info = (data.length > 75) ? data.substring[0,75] + '..' : data;

Answers:


424
info = (data[:75] + '..') if len(data) > 75 else data

58
我可能会更改条件len(data) > 77以说明双点(仅截断最后一个字符而仅将其替换为点是没有意义的)。
哈森

5
@hasenj:这与原始代码不符,但这是一个很好的建议,我应该首先指出。
Marcelo Cantos

2
注意,包含的括号当然是可选的。
泰勒·埃德米斯顿

10
@TaylorEdmiston是的,但是对于那些不记得他们每天使用的5-10种语言的所有优先规则的人来说,它们非常有用。
Marcelo Cantos

2
@安东尼一片
马塞洛·

126

甚至更短:

info = data[:75] + (data[75:] and '..')

2
有趣的方法。尽管它仍然是一种复合材料。^^
令人愉快的2010年

3
如果包含“ ..”,此解决方案是否不包含77个字符?
Mark Chackerian 2011年

这不是执行两次切片操作吗?当性能至关重要时,我想知道与说stackoverflow.com/a/52279347/1834057相比,它的性能如何
Nicholas Hamilton Hamilton

1
当然,原始答案很好,但是Marcelo的答案更好,因为它更明确,更易读(也就是Pythonic)。
sitnarf '19

114

更简洁:

data = data[:75]

如果少于75个字符,则不会更改。


9
如果字符串被截断,大概他想附加一个省略号。
FogleBird 2010年

4
您是对的-我从没注意到。除了其他答案,我想不出更好的方法。
尼尔2010年

82

如果您使用的是Python 3.4+,则可以textwrap.shorten从标准库中使用:

折叠并截断给定的文本以适合给定的宽度。

首先,文本中的空格被折叠(所有空格均由单个空格代替)。如果结果适合宽度,则将其返回。否则,将从末尾放置足够的单词,以使其余单词加上占位符适合宽度:

>>> textwrap.shorten("Hello  world!", width=12)
'Hello world!'
>>> textwrap.shorten("Hello  world!", width=11)
'Hello [...]'
>>> textwrap.shorten("Hello world", width=10, placeholder="...")
'Hello...'

8
它似乎在很长的字符串(没有空格)上乱七八糟,只输出省略号。
elBradford

5
@elBradford(和其他感兴趣的人):这是因为会shorten()截断单词,而不是单个字符。我进行了搜索,但似乎没有方法可以配置shorten()TextWrapper裁剪单个字符而不是单词的实例。
Acsor

而且它具有消除换行符的烦人的副作用
havlock

这不能解决OP的问题。它会逐字截断,甚至删除空格。
Florian Wendelborn



9

使用正则表达式:

re.sub(r'^(.{75}).*$', '\g<1>...', data)

长字符串被截断:

>>> data="11111111112222222222333333333344444444445555555555666666666677777777778888888888"
>>> re.sub(r'^(.{75}).*$', '\g<1>...', data)
'111111111122222222223333333333444444444455555555556666666666777777777788888...'

较短的字符串永远不会被截断:

>>> data="11111111112222222222333333"
>>> re.sub(r'^(.{75}).*$', '\g<1>...', data)
'11111111112222222222333333'

这样,您还可以“剪切”字符串的中间部分,这在某些情况下会更好:

re.sub(r'^(.{5}).*(.{5})$', '\g<1>...\g<2>', data)

>>> data="11111111112222222222333333333344444444445555555555666666666677777777778888888888"
>>> re.sub(r'^(.{5}).*(.{5})$', '\g<1>...\g<2>', data)
'11111...88888'

当字符串中有空格时,这是行不通的
holms 2015年

为什么在这种简单情况下使用正则表达式?
Bora M. Alper

5

如果满足以下条件,则此方法不使用任何方法:

data[:75] + bool(data[75:]) * '..'


4
我写它只是为了表明它是可能的。这违反了python的可读性哲学。与其他基于“ if”的方法相比,它没有任何性能优势。我从不使用它,也不建议您也使用它。
萨桑

4
limit = 75
info = data[:limit] + '..' * (len(data) > limit)

1
这是最优雅的解决方案。另外,我会将字符数限制(在这种情况下75)提取到变量中,以避免不一致。limit = 75; info = data[:limit] + '..' * (len(data) > limit)
ekauffmann '18 -10-25

3

另一个解决方案。使用True和,最后False您会得到有关测试的一些反馈。

data = {True: data[:75] + '..', False: data}[len(data) > 75]

2

这只是在:

n = 8
s = '123'
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]
s = '12345678'
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]
s = '123456789'     
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]
s = '123456789012345'
print  s[:n-3] + (s[n-3:], '...')[len(s) > n]

123
12345678
12345...
12345...

前面所有答案都忽略了OP真正想要的东西-输出字符串不能超过75个字符。感谢理解“不做我想说的,做我想做的”编程原理。为了完整起见,您可以通过添加以下内容来修复n <3的特殊情况:如果n> 2 else s [:n]
Dave

1
       >>> info = lambda data: len(data)>10 and data[:10]+'...' or data
       >>> info('sdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsdf')
           'sdfsdfsdfs...'
       >>> info('sdfsdf')
           'sdfsdf'
       >>> 

1
请解释您的答案?
Gwenc37 2014年

此函数的类似示例def info2(data):如果len(data)> 10:返回data [:10] +'...'else:以函数样式ex = lambda x返回数据无名设计的lambda指令: x + 1 def ex(x):返回x + 1
Spouk

1

您实际上无法像执行动态分配的C字符串那样“截断” Python字符串。Python中的字符串是不可变的。您可以按照其他答案中的说明对字符串进行切片,从而生成仅包含切片偏移量和步长定义的字符的新字符串。在某些(非实际)情况下,这可能会有些烦人,例如当您选择Python作为您的采访语言并且采访者要求您就地从字符串中删除重复的字符时。h


1
info = data[:min(len(data), 75)

仅代码答案通常被认为是低质量的。您能在答案中添加解释吗?
Lemon Kazi

0

不需要正则表达式,但是您确实想使用字符串格式而不是接受的答案中的字符串串联。

这可能是将字符串截断data为75个字符的最典型的Python方法。

>>> data = "saddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddsadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
>>> info = "{}..".format(data[:75]) if len(data) > 75 else data
>>> info
'111111111122222222223333333333444444444455555555556666666666777777777788888...'

我觉得很有趣,因为您的saddddddd...字符串变成了111111...:)我知道这是一个复制粘贴的错字,对于正则表达式我也同意。
akarilimano

0

这是我作为新String类的一部分制作的函数...它允许添加后缀(如果字符串是修剪后的大小,并且添加的长度足够长-尽管您无需强制使用绝对大小)

我当时正在改变一些事情,因此有一些无用的逻辑成本(例如_truncate ...),在此不再需要,并且顶部有回报。

但是,它仍然是截断数据的好功能...

##
## Truncate characters of a string after _len'nth char, if necessary... If _len is less than 0, don't truncate anything... Note: If you attach a suffix, and you enable absolute max length then the suffix length is subtracted from max length... Note: If the suffix length is longer than the output then no suffix is used...
##
## Usage: Where _text = 'Testing', _width = 4
##      _data = String.Truncate( _text, _width )                        == Test
##      _data = String.Truncate( _text, _width, '..', True )            == Te..
##
## Equivalent Alternates: Where _text = 'Testing', _width = 4
##      _data = String.SubStr( _text, 0, _width )                       == Test
##      _data = _text[  : _width ]                                      == Test
##      _data = ( _text )[  : _width ]                                  == Test
##
def Truncate( _text, _max_len = -1, _suffix = False, _absolute_max_len = True ):
    ## Length of the string we are considering for truncation
    _len            = len( _text )

    ## Whether or not we have to truncate
    _truncate       = ( False, True )[ _len > _max_len ]

    ## Note: If we don't need to truncate, there's no point in proceeding...
    if ( not _truncate ):
        return _text

    ## The suffix in string form
    _suffix_str     = ( '',  str( _suffix ) )[ _truncate and _suffix != False ]

    ## The suffix length
    _len_suffix     = len( _suffix_str )

    ## Whether or not we add the suffix
    _add_suffix     = ( False, True )[ _truncate and _suffix != False and _max_len > _len_suffix ]

    ## Suffix Offset
    _suffix_offset = _max_len - _len_suffix
    _suffix_offset  = ( _max_len, _suffix_offset )[ _add_suffix and _absolute_max_len != False and _suffix_offset > 0 ]

    ## The truncate point.... If not necessary, then length of string.. If necessary then the max length with or without subtracting the suffix length... Note: It may be easier ( less logic cost ) to simply add the suffix to the calculated point, then truncate - if point is negative then the suffix will be destroyed anyway.
    ## If we don't need to truncate, then the length is the length of the string.. If we do need to truncate, then the length depends on whether we add the suffix and offset the length of the suffix or not...
    _len_truncate   = ( _len, _max_len )[ _truncate ]
    _len_truncate   = ( _len_truncate, _max_len )[ _len_truncate <= _max_len ]

    ## If we add the suffix, add it... Suffix won't be added if the suffix is the same length as the text being output...
    if ( _add_suffix ):
        _text = _text[ 0 : _suffix_offset ] + _suffix_str + _text[ _suffix_offset: ]

    ## Return the text after truncating...
    return _text[ : _len_truncate ]

1
每个参数和变量中的所有下划线是什么?
尼古拉斯·汉密尔顿,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.