Python cắt một chuỗi dài


244

Làm thế nào để cắt một chuỗi thành 75 ký tự trong Python?

Đây là cách nó được thực hiện trong JavaScript:

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

Câu trả lời:


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

58
Tôi sẽ thay đổi điều kiện có lẽ để tính len(data) > 77đến các dấu chấm kép (thật vô nghĩa khi chỉ cắt một ký tự cuối cùng để thay thế nó bằng một dấu chấm).
hasen

5
@hasenj: Điều đó sẽ không phù hợp với mã ban đầu, nhưng đó là một gợi ý tốt mà tôi nên chỉ ra ngay từ đầu.
Marcelo Cantos

2
Lưu ý rằng các parens bao gồm tất nhiên là tùy chọn.
Taylor Edmiston

10
@TaylorEdmiston Đúng, nhưng chúng khá hữu ích cho những người không nhớ tất cả các quy tắc ưu tiên trên 5 ngôn ngữ10 mà họ sử dụng hàng ngày.
Marcelo Cantos

2
@Anthony một lát
Marcelo Cantos

126

Thậm chí ngắn hơn:

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

2
Cách tiếp cận hài hước để làm điều đó. Mặc dù nó vẫn là một lớp lót tổng hợp. ^^
Vui vẻ

3
giải pháp này không có 77 ký tự nếu bạn bao gồm '..'?
Mark Chackerian

Đây không phải là thực hiện hai hoạt động lát? Tôi tự hỏi làm thế nào điều này thực hiện so với stackoverflow.com/a/52279347/1834057 , khi hiệu suất là rất quan trọng
Nicholas Hamilton

1
Chắc chắn, câu trả lời ban đầu tốt đẹp, nhưng câu trả lời của Marcelo tốt hơn vì nó rõ ràng hơn và do đó dễ đọc hơn (và do đó là Pythonic).
sitnarf

114

Thậm chí ngắn gọn hơn:

data = data[:75]

Nếu nó ít hơn 75 ký tự thì sẽ không có thay đổi.


9
Có lẽ anh ta muốn một dấu chấm lửng được nối thêm nếu chuỗi bị cắt ngắn.
FogleBird

4
Bạn nói đúng - tôi không bao giờ nhận thấy điều đó. Tôi không thể nghĩ ra cách nào tốt hơn để làm điều đó hơn những câu trả lời khác.
neil

82

Nếu bạn đang sử dụng Python 3.4+, bạn có thể sử dụng textwrap.shortentừ thư viện chuẩn:

Thu gọn và cắt bớt văn bản đã cho để phù hợp với chiều rộng nhất định.

Đầu tiên khoảng trắng trong văn bản được thu gọn (tất cả khoảng trắng được thay thế bằng khoảng trắng đơn). Nếu kết quả phù hợp với chiều rộng, nó được trả về. Mặt khác, đủ các từ được bỏ từ cuối để các từ còn lại cộng với giữ chỗ phù hợp với chiều rộng:

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

8
Nó dường như tào lao quần của nó trên các chuỗi thực sự dài (không có khoảng trắng) và chỉ xuất ra dấu chấm lửng.
elBradford

5
@elBradford (và những người quan tâm khác): đó là vì shorten()cắt ngắn các từ , không phải các ký tự đơn. Tôi đã tìm kiếm nhưng dường như không có cách nào để định cấu hình shorten()hoặc một TextWrapperví dụ để cắt các ký tự đơn lẻ và không từ.
Acsor

Và nó có tác dụng phụ khó chịu khi loại bỏ ngắt dòng
havlock

Điều này không giải quyết được câu hỏi của OP. Nó cắt ngắn bằng từ và thậm chí loại bỏ khoảng trắng.
Florian Wendelborn

32

Đối với giải pháp Django (chưa được đề cập trong câu hỏi):

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

Hãy xem mã nguồn của Truncator để đánh giá vấn đề: https://github.com/django/django/blob/master/django/utils/text.py#L66

Liên quan đến việc cắt ngắn với Django: Cắt ngắn Django HTML


Điều này không cần thiết cặp vợ chồng logic cấp thấp để django. Sẽ không đề nghị nó.
Caveman


9

Với regex:

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

Các chuỗi dài được cắt ngắn:

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

Chuỗi ngắn hơn không bao giờ bị cắt ngắn:

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

Bằng cách này, bạn cũng có thể "cắt" phần giữa của chuỗi, đẹp hơn trong một số trường hợp:

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

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

cũng không hoạt động khi bạn có khoảng trắng trong chuỗi của mình
holms

Tại sao bạn sẽ sử dụng regex cho một trường hợp đơn giản như vậy?
Bora M. Alper

5

Phương pháp này không sử dụng bất kỳ nếu:

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


4
Tôi đã viết nó chỉ để cho thấy rằng nó có thể. Nó chống lại triết lý dễ đọc của python. Nó không có bất kỳ lợi thế về hiệu suất so với các phương thức dựa trên "nếu" khác. Tôi không bao giờ sử dụng nó và tôi không đề nghị bạn sử dụng nó quá.
Sassan

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

1
Đây là giải pháp thanh lịch nhất. Ngoài ra, tôi sẽ trích xuất giới hạn ký tự (trong trường hợp này 75) thành một biến để tránh sự không nhất quán. limit = 75; info = data[:limit] + '..' * (len(data) > limit)
ekauffmann

3

Một giải pháp khác. Với TrueFalsebạn nhận được một chút thông tin phản hồi về bài kiểm tra cuối cùng.

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

2

Điều này chỉ trong:

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

Tất cả các câu trả lời trước đó đều bỏ qua việc xem xét những gì OP thực sự muốn - một chuỗi đầu ra không dài hơn 75 ký tự. Kudos để hiểu nguyên tắc lập trình "đừng làm những gì tôi nói, làm những gì tôi muốn". Để hoàn thiện, bạn có thể sửa trường hợp góc của n <3 bằng cách nối thêm: if n> 2 other s [: n]
Dave

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

1
Hãy giải thích câu trả lời của bạn?
Gwenc37

ví dụ tương tự của hàm này def information2 (data): if len (data)> 10: return data [: 10] + '...' other: trả về lệnh lambda dữ liệu của thiết kế không tên theo kiểu chức năng ex = lambda x: x + 1 def ex (x): trả lại x + 1
Spouk

1

Bạn thực sự không thể "cắt" một chuỗi Python như bạn có thể thực hiện một chuỗi C được phân bổ động. Chuỗi trong Python là bất biến. Những gì bạn có thể làm là cắt một chuỗi như được mô tả trong các câu trả lời khác, thu được một chuỗi mới chỉ chứa các ký tự được xác định bởi các lát cắt và bước. Trong một số trường hợp (không thực tế), điều này có thể hơi khó chịu, chẳng hạn như khi bạn chọn Python làm ngôn ngữ phỏng vấn và người phỏng vấn yêu cầu bạn xóa các ký tự trùng lặp khỏi một chuỗi tại chỗ. Doh.


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

Mã chỉ trả lời thường được coi là chất lượng thấp. Bạn có thể thêm một lời giải thích cho câu trả lời của bạn.
Lemon Kazi

0

Không cần biểu thức chính quy nhưng bạn muốn sử dụng định dạng chuỗi hơn là nối chuỗi trong câu trả lời được chấp nhận.

Đây có lẽ là cách Pythonic kinh điển nhất để cắt xâu chuỗi dataở 75 ký tự.

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

Tôi thấy thật buồn cười khi saddddddd...chuỗi của bạn biến thành 111111...:) Tôi biết đó là một lỗi đánh máy sao chép và tôi đồng ý với bạn về các biểu thức thông thường.
akarilimano

0

Đây là một hàm tôi đã tạo như một phần của lớp String mới ... Nó cho phép thêm hậu tố (nếu chuỗi có kích thước sau khi cắt và thêm nó đủ dài - mặc dù bạn không cần phải ép kích thước tuyệt đối)

Tôi đang trong quá trình thay đổi một vài thứ xung quanh nên có một số chi phí logic vô dụng (ví dụ: _truncate ... chẳng hạn) khi nó không còn cần thiết và có sự trở lại ở đầu ...

Nhưng, nó vẫn là một chức năng tốt để cắt bớt dữ liệu ...

##
## 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
whats với tất cả các dấu gạch dưới trong mỗi đối số và biến duy nhất?
Nicholas Hamilton

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.