2010-06-01 68 views
64

我搜查了一下,但是竟然找不到答案。如何截斷NSString到一個設定的長度?

我有一個很長的NSString,我想縮短。我想要的最大長度是20個字符左右。我在某處讀到最好的解決方案是使用substringWithRange。這是截斷字符串的最佳方法嗎?

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]; 

它似乎有點微妙(如果字符串比最大長度短,就會崩潰)。我也不確定它是否是Unicode安全的。有沒有更好的方法來做到這一點?有沒有人有這個好的類別?

+6

...'-substringToIndex:'? – kennytm 2010-06-01 18:42:50

+0

相關,截斷字節計數,而不是組合字符:[在字或字符邊界截斷包含表情符或Unicode字符的字符串](http://stackoverflow.com/q/15775294/603977) – 2015-07-30 20:41:27

回答

116

其實關於「Unicode安全」的部分已經死了,因爲許多字符在unicode中組合,建議的答案沒有考慮。

例如,如果您想鍵入é。一種方法是輸入「e」(0x65)+組合重音「」(0x301)。現在,如果你像這樣輸入「咖啡廳」並截斷4個字符,你會得到「咖啡廳」。這可能會在某些地方造成問題。

如果你不關心這個,其他答案工作正常。否則,這樣做:

// 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]; 

注意,在這樣的範圍可能比您最初的範圍長度。在上面的咖啡廳示例中,即使您仍然有4個「字形」,您的範圍也會擴展爲5。如果您絕對需要的長度小於您所指定的長度,則需要檢查這一點。

+0

感謝您的回答。日本漢字受到你提到的組合口音問題的影響嗎?從使用你的解決方案,它似乎與漢字運作良好。 – 2010-06-11 09:38:49

+0

恐怕我不熟悉漢字字符,但我想他們都是單字符(unicode 0x4E00到0x9FAF),所以他們不應該需要這個。但是,我不知道... – mohsenr 2010-06-12 01:55:52

+0

@mohsenr我剛剛用「咖啡廳」的BEFORE和AFTER截斷(使用OP的解決方案)進行了測試,兩者的長度都是4.我認爲iOS認爲'é'是一個單個字符! – onmyway133 2013-11-04 09:46:36

3

可以使用三元操作:

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

或者超過最終結果的更多控制:

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

好的一行,謝謝亞歷克斯。 – 2010-06-11 09:40:47

6

這似乎有點微妙(崩潰,如果字符串的長度超出最大短長度)

那麼爲什麼不修復它的那部分呢?

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

很好的解決方法,謝謝。 – 2010-06-11 09:40:16

0

所有的NSString操作都是Unicode安全的,因爲NSString本質上是一個內部的unichar數組。即使字符串使用不同的編碼,它在顯示時也會轉換爲指定的編碼。

+4

實際上,不,它不完全是Unicode安全的,因爲一些Unicode字符使用多個unichar。您希望避免在這樣的序列中間分割字符串。因此需要像'rangeOfComposedCharacterSequenceAtIndex:'這樣的方法。 – JWWalker 2010-06-01 20:52:17

11

較短的解決方案是:

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

因爲這個答案是不實際在這份名單中,最簡單,最明智的一行:

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

太棒了!因爲我無法編輯一個字符錯字錯誤,所以我將它放在這裏:[myString subStringToIndex:20];應該是[myString substringToIndex:20]; – user23127 2014-06-02 12:57:22

+0

好抓 - 固定! – brandonscript 2014-06-02 15:19:54

+0

如果'myString.lenght'高於'20',我會引發異常。你必須先測試它 – 2014-09-11 12:32:54

0

如果你想截斷最終使用:

[fileName substringToIndex:anyNumber]; 

如果你想從開始到截斷:

[fileName substringFromIndex:anyNumber]; 
1

最簡單和很好的解決方案(用 「......」 在文本的末尾):

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

斯威夫特4

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

快樂編碼。