Pythonは長い文字列を切り捨てます


245

Pythonで文字列を75文字に切り捨てる方法を教えてください。

これはJavaScriptでどのように行われるかです:

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

回答:


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

58
おそらくlen(data) > 77、二重のドットを考慮して条件を変更します(最後の文字のみを切り捨ててドットに置き換えるだけでは意味がありません)。
Hasen

5
@hasenj:それは元のコードに適合しませんが、私が最初に指摘すべきだったのは良い提案です。
Marcelo Cantos 2013年

2
含まれる括弧はもちろんオプションです。
テイラーエドミストン2016年

10
@TaylorEdmiston正しいですが、日常的に使用する5〜10言語の優先順位ルールをすべて覚えていない人には非常に役立ちます。
Marcelo Cantos 2016年

2
@Anthony a slice
Marcelo Cantos

126

さらに短い:

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

2
それを行うための面白いアプローチ。それはまだ複合ワンライナーですが。^^
2010年

3
「..」を含めると、このソリューションに77文字が含まれませんか?
Mark Chackerian、2011年

これは2つのスライス操作を実行していませんか?パフォーマンスが重要な場合、これがstackoverflow.com/a/52279347/1834057と比較してどのように機能するのか疑問に思います
Nicholas Hamilton

1
確かに、元の答えはいいですが、Marceloの答えはより明確で読みやすい(したがってPythonic)ため、より優れています。
sitnarf

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 2017

5
@elBradford(および関心のある他の人):これは、単一の文字ではなく単語をshorten()切り捨てるためです。私は検索しましたが、単語ではなく単一の文字をクリップするように構成する方法やインスタンスがないようです。shorten()TextWrapper
Acsor 2017

そして、改行を削除するという厄介な副作用があります
havlock

これはOPの質問を解決しません。単語ごとに切り捨てられ、空白も削除されます。
フロリアンウェンデルボルン

32

Djangoソリューションの場合(質問には記載されていません):

from django.utils.text import Truncator
value = Truncator(value).chars(75)

問題を理解するには、Truncatatorのソースコードをご覧ください。https//github.com/django/django/blob/master/django/utils/text.py#L66

Djangoでの切り捨てについて: Django HTMLの切り捨て


これは不必要に低レベルのロジックをdjangoに結合します。それをお勧めしません。
穴居人


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

なぜこのような単純なケースで正規表現を使用するのですか?
ボラM.アルパー

5

次の場合、このメソッドは何も使用しません。

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


4
私はそれが可能であることを示すためだけにそれを書きました。Pythonの読みやすさの哲学に反しています。他の「if」ベースの方法と比較して、パフォーマンス上の利点はありません。私はそれを使用したことはありません。
Sassan

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

1
これは最もエレガントなソリューションです。さらに75、矛盾を回避するために、文字制限(この場合は)を変数に抽出します。limit = 75; info = data[:limit] + '..' * (len(data) > limit)
ekauffmann 2018年

3

さらに別のソリューション。とTrueFalseあなたは最後にテストについて少しフィードバックを得ます。

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のコーナーケースを次のように追加して修正できます:if 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):if len(data)> 10:return data [:10] + '...' else:return dataラムダ命令の名前のないデザインの機能スタイルex = lambda x: x + 1 def ex(x):return x + 1
Spouk

1

動的に割り当てられたC文字列を実行できるように、実際にはPython文字列を「切り捨て」ることはできません。Pythonの文字列は不変です。あなたができることは、他の答えで説明されているように文字列をスライスして、スライスのオフセットとステップで定義された文字のみを含む新しい文字列を生成することです。いくつかの(非実用的な)ケースでは、面接言語としてPythonを選択し、インタビュアーが文字列から重複する文字を削除するように要求する場合など、少し煩わしい場合があります。どー。


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

コードのみの回答は一般に低品質と見なされます。答えに説明を付けてください。
Lemon Kazi、

0

正規表現は必要ありませんが、受け入れられた回答では、文字列の連結ではなく文字列のフォーマットを使用する必要があります。

これはおそらく、data75 文字で文字列を切り捨てる最も標準的な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
すべての単一の引数と変数にすべての下線が付いているのはどうですか?
ニコラスハミルトン

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.