我在NSString中有一些数据,用冒号分隔:
@"John:Doe:1970:Male:Dodge:Durango"
我需要将此字符串的总长度限制为100个字符。但我还需要确保存在正确数量的冒号。
截断字符串的方法是合理的,但是还要添加额外的冒号,以便我可以将其解析为另一端的正确数量的字段?
例如,如果我的限制是18,你最终会得到这样的结果:
@"John:Doe:1970:Ma::"
这是我自己最新传递的更新版本。使用@blinkenlights算法:
+ (NSUInteger)occurrencesOfSubstring:(NSString *)substring inString:(NSString *)string {
// http://stackoverflow.com/a/5310084/878969
return [string length] - [[string stringByReplacingOccurrencesOfString:substring withString:@""] length] / [substring length];
}
+ (NSString *)truncateString:(NSString *)string toLength:(NSUInteger)length butKeepDelmiter:(NSString *)delimiter {
if (string.length <= length)
return string;
NSAssert(delimiter.length == 1, @"Expected delimiter to be a string containing a single character");
int numDelimitersInOriginal = [[self class] occurrencesOfSubstring:delimiter inString:string];
NSMutableString *truncatedString = [[string substringToIndex:length] mutableCopy];
int numDelimitersInTruncated = [[self class] occurrencesOfSubstring:delimiter inString:truncatedString];
int numDelimitersToAdd = numDelimitersInOriginal - numDelimitersInTruncated;
int index = length - 1;
while (numDelimitersToAdd > 0) { // edge case not handled here
NSRange nextRange = NSMakeRange(index, 1);
index -= 1;
NSString *rangeSubstring = [truncatedString substringWithRange:nextRange];
if ([rangeSubstring isEqualToString:delimiter])
continue;
[truncatedString replaceCharactersInRange:nextRange withString:delimiter];
numDelimitersToAdd -= 1;
}
return truncatedString;
}
请注意,我认为此解决方案不会处理来自CRD的边缘情况,其中分隔符的数量小于限制。
我需要正确数量的冒号的原因是服务器上的代码将在冒号上拆分并期望得到5个字符串。
您可以假设冒号分隔的字符串的组件本身不包含冒号。
答案 0 :(得分:3)
当最后一个colonsToAdd
中的一个或多个字符是冒号时,您当前的算法将无法产生正确的结果。
您可以改用此方法:
NSMutableString
答案 1 :(得分:2)
我倾向于@dasblinkenlight,毕竟它只是一个算法,但这里有一些代码。很少有现代短片 - 使用旧的编译器。 ARC假设。不会声称它有效或美观,但它确实起作用并处理边缘情况(重复冒号,限制太多字段):
- (NSString *)abbreviate:(NSString *)input limit:(NSUInteger)limit
{
NSMutableArray *fields = [[input componentsSeparatedByString:@":"] mutableCopy];
NSUInteger colonCount = fields.count - 1;
if (colonCount >= limit)
return [@"" stringByPaddingToLength:limit withString:@":" startingAtIndex:0];
NSUInteger nonColonsRemaining = limit - colonCount;
for (NSUInteger ix = 0; ix <= colonCount; ix++)
{
if (nonColonsRemaining > 0)
{
NSString *fieldValue = [fields objectAtIndex:ix];
NSUInteger fieldLength = fieldValue.length;
if (fieldLength <= nonColonsRemaining)
nonColonsRemaining -= fieldLength;
else
{
[fields replaceObjectAtIndex:ix withObject:[fieldValue substringToIndex:nonColonsRemaining]];
nonColonsRemaining = 0;
}
}
else
[fields replaceObjectAtIndex:ix withObject:@""];
}
return [fields componentsJoinedByString:@":"];
}