如何将NSString截断为设定长度?

时间:2010-06-01 18:33:43

标签: iphone objective-c cocoa string

我搜索过,但令人惊讶的是找不到答案。

我想要缩短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安全的。有没有更好的方法呢?有没有人有这个很好的类别?

11 个答案:

答案 0 :(得分:120)

实际上关于“Unicode安全”的部分已经死了,因为许多字符组合在unicode中,建议的答案不考虑。

例如,如果要输入é。一种方法是键入“e”(0x65)+组合重音“”(0x301)。现在,如果您输入这样的“café”并截断4个字符,您将获得“cafe”。这可能会在某些地方引起问题。

如果你不关心这个问题,其他答案也可以。否则,请执行以下操作:

// 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的长度。如果你的长度必须小于你指定的长度,你需要检查这个。

答案 1 :(得分:14)

由于这个答案实际上并不在这个列表中,所以最简单,最明智的单行:

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;

答案 2 :(得分:11)

更短的解决方案是:

NSString *shortString = ([myString length]>MINLENGTH ? [myString substringToIndex:MINLENGTH] : myString);

答案 3 :(得分:7)

  

看起来有点微妙(如果字符串短于最大长度则崩溃)

那么为什么不解决它的一部分呢?

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

答案 4 :(得分: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];

答案 5 :(得分: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

答案 6 :(得分:2)

最简单,最好的解决方案(文本末尾有3个点):

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

答案 7 :(得分:2)

Swift 4

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

快乐编码。

答案 8 :(得分:2)

扩展名以截断不同位置(头,尾或中间)。

Swift 4.2及更高版本

extension String {
    enum TruncationPosition {
        case head
        case middle
        case tail
    }

   func truncated(limit: Int, position: TruncationPosition = .tail, leader: String = "...") -> String {
        guard self.count >= limit else { return self }

        switch position {
        case .head:
            return leader + self.suffix(limit)
        
        case .middle:
            let halfCount = (limit - leader.count).quotientAndRemainder(dividingBy: 2)
            let headCharactersCount = halfCount.quotient + halfCount.remainder
            let tailCharactersCount = halfCount.quotient
            return String(self.prefix(headCharactersCount)) + leader + String(self.suffix(tailCharactersCount))
        
        case .tail:
            return self.prefix(limit) + leader
        }
    }
}

答案 9 :(得分:0)

所有NSString操作都是Unicode安全的,因为NSString本质上是一个unichar数组。即使字符串采用不同的编码,它也会在显示时转换为指定的编码。

答案 10 :(得分:0)

如果要截断最终用途:

[fileName substringToIndex:anyNumber];

如果你想从开始截断:

[fileName substringFromIndex:anyNumber];