如何将 NSString 截断为设定的长度?
Posted
技术标签:
【中文标题】如何将 NSString 截断为设定的长度?【英文标题】:How can I truncate an NSString to a set length? 【发布时间】:2010-06-01 18:33:42 【问题描述】:我搜索了,但令人惊讶的是找不到答案。
我想缩短一个很长的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 安全的。有更好的方法吗?有人对此有一个不错的类别吗?
【问题讨论】:
...-substringToIndex:
?
相关,按字节数截断而不是组合字符:Truncate string containing emoji or Unicode characters at word or character boundary
【参考方案1】:
实际上,关于“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];
请注意,通过这种方式,您的范围可能会比您的初始范围长度长。在上面的咖啡馆示例中,您的范围将扩展到 5 的长度,即使您仍然有 4 个“字形”。如果您绝对需要长度小于您指定的长度,则需要检查这一点。
【讨论】:
感谢您的回答。日语汉字是否受到您提到的组合重音问题的影响?通过使用您的解决方案,它似乎与汉字配合得很好。 恐怕我对汉字字符不是很熟悉,但我想它们都是单个字符(unicode 0x4E00 到 0x9FAF)所以他们不应该需要这个。但同样,我不确定...... @mohsenr 我刚刚在截断前后(使用 OP 的解决方案)测试了“café”,两者都给出了 4 的长度。我认为 ios 将 'é' 视为单个字符! ! 'é' = 0xE9 和'é' = 0x65 0x301。如果第一种情况,第二个 5 中的长度为 4。【参考方案2】:斯威夫特 4
let trimToCharacter = 20
let shortString = String(myString.prefix(trimToCharacter))
快乐编码。
【讨论】:
【参考方案3】:由于此答案实际上不在此列表中,因此最简单,最明智的单行:
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;
【讨论】:
太棒了!因为我不能编辑一个字符拼写错误,所以我把它放在这里:[myString subStringToIndex:20];应该是 [myString substringToIndex:20]; 如果myString.lenght
高于20
,我会抛出异常。您必须先对其进行测试【参考方案4】:
更短的解决方案是:
NSString *shortString = ([myString length]>MINLENGTH ? [myString substringToIndex:MINLENGTH] : myString);
【讨论】:
【参考方案5】:看起来有点微妙(如果字符串短于最大长度会崩溃)
那为什么不修复那部分呢?
NSRange stringRange = 0, MIN([myString length], 20);
【讨论】:
【参考方案6】:可以使用三元运算:
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];
【讨论】:
【参考方案7】:最简单又好看的解决方案(文末3个点):
NSString *newText = [text length] > intTextLimit ?
[[text substringToIndex:intTextLimit] stringByAppendingString:@"..."] :
text;
【讨论】:
你应该使用“…”(Option + ;)而不是 3 个点,它只需要一个字符。【参考方案8】: //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
【讨论】:
【参考方案9】:在不同位置(头部、尾部或中间)截断的扩展。
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
【讨论】:
【参考方案10】:所有 NSString 操作都是 Unicode 安全的,因为 NSString 在内部本质上是一个 unichar 数组。即使字符串采用不同的编码,它也会在显示时转换为您指定的编码。
【讨论】:
实际上,不,它并不完全是 Unicode 安全的,因为某些 Unicode 字符使用多个 unichar。您希望避免在这样的序列中间拆分字符串。因此需要像rangeOfComposedCharacterSequenceAtIndex:
这样的方法。【参考方案11】:
如果您想从最终用途中截断:
[fileName substringToIndex:anyNumber];
如果你想从头开始截断:
[fileName substringFromIndex:anyNumber];
【讨论】:
以上是关于如何将 NSString 截断为设定的长度?的主要内容,如果未能解决你的问题,请参考以下文章