2010-06-01 29 views
64

Tôi đã tìm kiếm, nhưng đáng ngạc nhiên không thể tìm thấy câu trả lời.Làm cách nào để cắt ngắn NSString thành độ dài được đặt?

Tôi có số dài NSString mà tôi muốn rút ngắn. Tôi muốn độ dài tối đa khoảng 20 ký tự. Tôi đọc ở đâu đó rằng giải pháp tốt nhất là sử dụng substringWithRange. Đây có phải là cách tốt nhất để cắt ngắn chuỗi không?

NSRange stringRange = {0,20}; 
NSString *myString = @"This is a string, it's a very long string, it's a very long string indeed"; 
NSString *shortString = [myString substringWithRange:stringRange]; 

Có vẻ hơi tinh tế (treo nếu chuỗi ngắn hơn độ dài tối đa). Tôi cũng không chắc nó có an toàn với Unicode hay không. Có cách nào tốt hơn để làm điều đó không? Có ai có một loại tốt đẹp cho điều này?

+6

... '-substringToIndex:'? – kennytm

+0

Liên quan, cắt ngắn theo số byte thay vì ký tự được soạn: [Chuỗi cắt ngắn chứa biểu tượng cảm xúc hoặc ký tự Unicode ở ranh giới từ hoặc ký tự] (http://stackoverflow.com/q/15775294/603977) –

Trả lời

116

Thực ra phần về "an toàn Unicode" đã bị chết, vì nhiều ký tự kết hợp trong unicode mà các câu trả lời được đề xuất không xem xét.

Ví dụ: nếu bạn muốn nhập é. Một cách để thực hiện nó là gõ "e" (0x65) + dấu kết hợp "́" (0x301). Bây giờ, nếu bạn nhập "quán cà phê" như thế này và cắt bớt 4 ký tự, bạn sẽ nhận được "quán cà phê". Điều này có thể gây ra vấn đề ở một số nơi.

Nếu bạn không quan tâm đến điều này, các câu trả lời khác sẽ hoạt động tốt. Nếu không, hãy thực hiện việc này:

// define the range you're interested in 
NSRange stringRange = {0, MIN([myString length], 20)}; 

// adjust the range to include dependent chars 
stringRange = [myString rangeOfComposedCharacterSequencesForRange:stringRange]; 

// Now you can create the short string 
NSString *shortString = [myString substringWithRange:stringRange]; 

Lưu ý rằng theo cách này, phạm vi của bạn có thể dài hơn độ dài phạm vi ban đầu. Trong ví dụ về quán cà phê ở trên, phạm vi của bạn sẽ mở rộng đến độ dài 5, mặc dù bạn vẫn có 4 "hình tượng". Nếu bạn hoàn toàn cần phải có độ dài ít hơn so với những gì bạn đã chỉ ra, bạn cần phải kiểm tra điều này.

+0

Cảm ơn câu trả lời. Chữ Hán có bị ảnh hưởng bởi vấn đề giọng nói kết hợp mà bạn đã đề cập không? Từ việc sử dụng giải pháp của bạn, có vẻ như nó hoạt động tốt với kanji. –

+0

Tôi sợ rằng tôi không quen thuộc với các ký tự kanji, nhưng tôi cho rằng chúng là tất cả các ký tự đơn (unicode 0x4E00 đến 0x9FAF) nên chúng không cần điều này. Nhưng một lần nữa, tôi không chắc chắn ... – mohsenr

+0

@mohsenr Tôi vừa thử nghiệm với "quán cà phê" TRƯỚC KHI SAU cắt (sử dụng giải pháp của OP), cả hai đều cho độ dài 4. Tôi nghĩ iOS coi 'é' là một Nhân vật SINGLE !!! – onmyway133

3

có thể sử dụng một hoạt động ternary:

NSString *shortString = (stringRange.length <= [myString length]) ? myString : [myString substringWithRange:stringRange]; 

Hoặc cho kiểm soát nhiều hơn kết quả cuối cùng:

if (stringRange.length > [myString length]) 
    // throw exception, ignore error, or set shortString to myString 
else 
    shortString = [myString substringWithRange:stringRange]; 
+0

Đẹp một lớp lót, cảm ơn Alex. –

6

Có vẻ như một chút tinh tế (tai nạn nếu chuỗi ngắn hơn mức tối đa length)

Sau đó, tại sao không khắc phục được phần đó?

NSRange stringRange = {0, MIN([myString length], 20)}; 
+0

Giải pháp tốt, cảm ơn. –

0

Tất cả các hoạt động NSString là an toàn Unicode, vì NSString thực chất là mảng unichar trong nội bộ. Ngay cả khi chuỗi trong một mã hóa khác, nó được chuyển đổi sang mã hóa được chỉ định của bạn khi nó được hiển thị.

+4

Trên thực tế, không, nó không chính xác Unicode an toàn, vì một số ký tự Unicode sử dụng nhiều hơn một unichar. Bạn muốn tránh tách một chuỗi ở giữa chuỗi đó. Do đó sự cần thiết cho các phương thức như 'rangeOfComposedCharacterSequenceAtIndex:'. – JWWalker

11

Một giải pháp ngắn hơn là:

NSString *shortString = ([myString length]>MINLENGTH ? [myString substringToIndex:MINLENGTH] : myString); 
2
//Short the string if string more than 45 chars 
    if([self.tableCellNames[indexPath.section] length] > 40) { 

     // define the range you're interested in 
     NSRange stringRange = {0, MIN([self.tableCellNames[indexPath.section] length], 40)}; 

     // adjust the range to include dependent chars 
     stringRange = [self.tableCellNames[indexPath.section] 
         rangeOfComposedCharacterSequencesForRange:stringRange]; 

     // Now you can create the short string 
     NSString *shortStringTitle = [self.tableCellNames[indexPath.section] substringWithRange:stringRange]; 

     shortStringTitle = [shortStringTitle stringByAppendingString:@"..."]; 

     titleLabel.text = shortStringTitle; 

    } else { 

     titleLabel.text = self.tableCellNames[indexPath.section]; 
    } 

// VKJ

12

Kể từ khi câu trả lời này không phải là thực sự trong danh sách này, đơn giản nhất và hợp lý nhất một liner:

NSString *myString = @"This is a string, it's a very long string, it's a very long string indeed"; 
myString = (myString.length > 20) ? [myString substringToIndex:20] : myString; 
+0

Tuyệt vời! Bởi vì tôi không thể sửa một sai lầm typo ký tự tôi sẽ đặt nó ở đây: [myString subStringToIndex: 20]; nên là [myString substringToIndex: 20]; – user23127

+0

Bắt tốt - cố định! – brandonscript

+0

Tôi ném một ngoại lệ nếu 'myString.lenght' cao hơn' 20'. Bạn phải kiểm tra nó trước –

0

Nếu bạn muốn cắt ngắn từ mục đích sử dụng cuối cùng:

[fileName substringToIndex:anyNumber]; 

Nếu bạn muốn cắt ngắn từ đầu:

[fileName substringFromIndex:anyNumber]; 
1

Giải pháp đơn giản nhất và đẹp (với "..." ở cuối văn bản):

NSString *newText = [oldText length] > intTextLimit ? [[oldText substringToIndex:intTextLimit] stringByAppendingString:@"..."] : oldText; 
1

Swift 4

let trimToCharacter = 20 
let shortString = String(myString.prefix(trimToCharacter)) 

Mã hóa hạnh phúc.

Các vấn đề liên quan