Python tronca una lunga stringa


246

Come si fa a troncare una stringa di 75 caratteri in Python?

Ecco come si fa in JavaScript:

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

Risposte:


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

58
Vorrei cambiare la condizione forse per len(data) > 77tenere conto dei punti doppi (è inutile troncare solo l'ultimo carattere solo per sostituirlo con un punto).
hasen

5
@hasenj: Questo non sarebbe conforme al codice originale, ma è un buon suggerimento che avrei dovuto sottolineare in primo luogo.
Marcelo Cantos,

2
Si noti che le parentesi incluse sono ovviamente opzionali.
Taylor Edmiston,

10
@TaylorEdmiston Vero, ma sono molto utili per coloro che non ricordano tutte le regole di precedenza nelle 5-10 lingue che usano quotidianamente.
Marcelo Cantos,

2
@Anthony a slice
Marcelo Cantos,

126

Ancora più breve:

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

2
Approccio divertente per farlo. Sebbene sia ancora un rivestimento composito. ^^
Allegro

3
questa soluzione non ha 77 caratteri se includi '..'?
Mark Chackerian,

non sta eseguendo due operazioni di slice? Mi chiedo come funzioni rispetto a stackoverflow.com/a/52279347/1834057 , quando le prestazioni sono cruciali
Nicholas Hamilton,

1
Certo, bella risposta originale, ma la risposta di Marcelo è migliore poiché è più esplicita e quindi leggibile (e quindi Pythonic).
sitnarf,

114

Ancora più conciso:

data = data[:75]

Se contiene meno di 75 caratteri, non ci saranno cambiamenti.


9
Presumibilmente vuole che vengano aggiunti dei puntini di sospensione se la stringa viene troncata.
FogleBird,

4
Hai ragione, non l'ho mai notato. Non riesco a pensare a un modo migliore per farlo rispetto ad altre risposte.
neil,

82

Se si utilizza Python 3.4+, è possibile utilizzare textwrap.shortendalla libreria standard:

Comprimi e tronca il testo indicato per adattarlo alla larghezza data.

Innanzitutto lo spazio bianco nel testo viene compresso (tutto lo spazio bianco viene sostituito da spazi singoli). Se il risultato si adatta alla larghezza, viene restituito. Altrimenti, vengono lasciate abbastanza parole dalla fine in modo che le parole rimanenti più il segnaposto si adattino alla larghezza:

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

8
Sembra che si caghi i pantaloni su corde molto lunghe (senza spazi) e genera solo i puntini di sospensione.
elBradford,

5
@elBradford (e altri interessati): questo perché shorten()tronca le parole , non i singoli caratteri. Ho cercato ma non sembra esserci un modo per configurare shorten()o TextWrapperun'istanza per tagliare singoli caratteri e non parole.
Acsor,

E ha il fastidioso effetto collaterale di rimuovere le interruzioni di riga
havlock

Questo non risolve la domanda di OP. Si tronca per parola e rimuove persino gli spazi bianchi.
Florian Wendelborn,



9

Con regex:

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

Le stringhe lunghe vengono troncate:

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

Le stringhe più brevi non vengono mai troncate:

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

In questo modo, puoi anche "tagliare" la parte centrale della stringa, che in alcuni casi è più bella:

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

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

bene che non ha funzionato quando hai spazi nella tua stringa
holms

Perché dovresti usare regex per un caso così semplice?
Bora M. Alper,

5

Questo metodo non ne utilizza nessuno se:

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


4
L'ho scritto solo per dimostrare che è possibile. È contro la filosofia di leggibilità di Python. Non ha alcun vantaggio in termini di prestazioni rispetto ad altri metodi basati su "if". Non lo uso mai e non suggerisco di usarlo anche tu.
Sassan,

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

1
Questa è la soluzione più elegante. Inoltre vorrei estrarre il limite di caratteri (in questo caso 75) in una variabile per evitare incoerenze. limit = 75; info = data[:limit] + '..' * (len(data) > limit)
Ekauffmann,

3

Ancora un'altra soluzione. Con Truee Falseotterrai un piccolo feedback sul test alla fine.

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

2

Questo solo dentro:

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...

Tutte le risposte precedenti trascurano di considerare ciò che l'OP voleva davvero: una stringa di output non più lunga di 75 caratteri. Complimenti per aver compreso il principio di programmazione "non fare quello che dico, fai quello che voglio". Per completezza, è possibile correggere il caso angolare di n <3 aggiungendo: se n> 2 altro s [: n]
Dave

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

1
Per favore, spiega la tua risposta?
Gwenc37,

esempio simile di questa funzione def info2 (data): if len (data)> 10: return data [: 10] + '...' altrimenti: restituisce i dati lambda istruzione del design senza nome in uno stile funzionale ex = lambda x: x + 1 def ex (x): return x + 1
Spouk

1

In realtà non puoi "troncare" una stringa Python come puoi fare una stringa C allocata dinamicamente. Le stringhe in Python sono immutabili. Quello che puoi fare è tagliare una stringa come descritto in altre risposte, producendo una nuova stringa contenente solo i caratteri definiti dagli offset della fetta e dal passaggio. In alcuni casi (non pratici) questo può essere un po 'fastidioso, come quando scegli Python come lingua dell'intervista e l'intervistatore ti chiede di rimuovere i caratteri duplicati da una stringa sul posto. Doh.


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

Le risposte solo al codice sono generalmente considerate di bassa qualità. Potresti aggiungere una spiegazione alla tua risposta.
Lemon Kazi,

0

Non è necessaria un'espressione regolare ma si desidera utilizzare la formattazione della stringa anziché la concatenazione della stringa nella risposta accettata.

Questo è probabilmente il modo più canonico e pitone di troncare la stringa dataa 75 caratteri.

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

Ho trovato divertente il modo in cui la tua saddddddd...stringa si trasforma 111111...:) So che è un refuso copia-incolla e sono d'accordo con te sulle espressioni regolari.
akarilimano,

0

Ecco una funzione che ho fatto come parte di una nuova classe String ... Permette di aggiungere un suffisso (se la stringa ha dimensioni dopo il taglio e l'aggiunta è abbastanza lunga - anche se non è necessario forzare la dimensione assoluta)

Stavo cambiando alcune cose, quindi ci sono alcuni costi logici inutili (se _truncate ... per esempio) in cui non è più necessario e c'è un ritorno in alto ...

Tuttavia, è ancora una buona funzione per troncare i dati ...

##
## 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
cosa succede con tutti i trattini bassi in ogni singolo argomento e variabile?
Nicholas Hamilton,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.