Ios 截断带分隔符的NSString而不删除分隔符

Ios 截断带分隔符的NSString而不删除分隔符,ios,objective-c,regex,string,Ios,Objective C,Regex,String,我在NSString中有一些数据,用冒号分隔: @"John:Doe:1970:Male:Dodge:Durango" 我需要将此字符串的总长度限制为100个字符。但我还需要确保存在正确数量的冒号 什么是一种合理的方法来截断字符串,同时添加额外的冒号,这样我就可以在另一端将其解析为正确数量的字段 例如,如果我的限制是18,你会得到这样的结果: @"John:Doe:1970:Ma::" 这是我最新的通行证的更新版本。使用@blinkenlights算法: + (NSUInteger)occu

我在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;
}
+(NSUInteger)子字符串的发生率:(NSString*)子字符串inString:(NSString*)字符串{
// http://stackoverflow.com/a/5310084/878969
返回[string length]-[[string stringByReplacingOccurrencesOfString:substring with string:@“]length]/[substring length];
}
+(NSString*)truncateString:(NSString*)字符串长度:(NSINTEGER)长度但保留PDELMITER:(NSString*)分隔符{
如果(string.length 0){//此处不处理边大小写
NSRange nextRange=NSMakeRange(索引,1);
指数-=1;
NSString*rangeSubstring=[截断字符串substringWithRange:nextRange];
if([rangeSubstring IsequalString:分隔符])
继续;
[truncatedString ReplaceCharactersRange:nextRange with String:delimiter];
numDelimitersToAdd-=1;
}
返回截断字符串;
}
请注意,我认为此解决方案不会处理CRD中分隔符数量小于限制的边缘情况

我需要正确的冒号数的原因是服务器上的代码将在冒号上拆分,并期望返回5个字符串


您可以假设冒号分隔字符串的组件本身不包含冒号。

如果最后一个
冒号加载中的一个或多个字符是冒号,则当前算法将不会产生正确的结果

您可以改用这种方法:

  • 将字符串剪切为100个字符,并将字符存储在
    NSMutableString
  • 计算冒号的数量,然后从所需的数字中减去该数字
  • 从字符串的后面开始,用冒号替换非冒号字符,直到获得正确的冒号数

如果最后一个
冒号中的一个或多个字符是冒号,则当前算法将无法生成正确的结果

您可以改用这种方法:

  • 将字符串剪切为100个字符,并将字符存储在
    NSMutableString
  • 计算冒号的数量,然后从所需的数字中减去该数字
  • 从字符串的后面开始,用冒号替换非冒号字符,直到获得正确的冒号数

    • 我倾向于@dasblinkenlight,它毕竟只是一个算法,但这里有一些代码。很少有现代速记——使用旧的编译器。这是假定的。不会声称它是高效的或漂亮的,但它确实可以工作并处理边缘情况(重复冒号,限制的字段太多):

      -(NSString*)缩写:(NSString*)输入限制:(nsinteger)限制
      {
      NSMutableArray*字段=[[InputComponentsSeparatedByString:@]:“]mutableCopy];
      NSU整数列数=fields.count-1;
      如果(列数>=限制)
      返回[@”“stringByPaddingToLength:limit with string:@:“startingAtIndex:0];
      NSUTEGER NONCOLONSREMAING=限制-列数;
      对于(整数ix=0;ix 0)
      {
      NSString*fieldValue=[fields objectAtIndex:ix];
      NSUInteger fieldLength=fieldValue.length;
      
      如果(fieldLength我倾向于@dasblinkenlight,它毕竟只是一个算法,但这里有一些代码。很少有现代速记-使用旧编译器。ARC假设。不会声称它是有效的或漂亮的,但它确实工作并处理边缘情况(重复冒号,太多字段限制):

      -(NSString*)缩写:(NSString*)输入限制:(nsinteger)限制
      {
      NSMutableArray*字段=[[InputComponentsSeparatedByString:@]:“]mutableCopy];
      NSU整数列数=fields.count-1;
      如果(列数>=限制)
      返回[@”“stringByPaddingToLength:limit with string:@:“startingAtIndex:0];
      NSUTEGER NONCOLONSREMAING=限制-列数;
      对于(整数ix=0;ix 0)
      {
      NSString*fieldValue=[fields objectAtIndex:ix];
      NSUInteger fieldLength=fieldValue.length;
      
      如果(fieldLength显示您迄今为止尝试过的代码。我不确定是否理解您的问题。如果字符串的长度>100,您将截断它,但如果长度<100,您还希望添加冒号以达到长度=100?不可能。101个冒号的字符串不能被此规则截断。旁注-为什么限制?您是否与某些用户交互古老的COBOL系统?现在是2013年。服务器应该比这更智能。如果服务器有一些限制,那么服务器应该强制执行限制,而不是每个访问它的客户端。@rmaddy在分析系统中,该值被压缩到一个非设计用来保存它的字段中。该字段的限制是100个字符。显示您没有看到的代码ried到目前为止。我不确定我是否理解你的问题。如果字符串长度>100,你会截断它,但如果长度<100,你还想添加冒号以达到长度=100?不可能。101个冒号的字符串不能被这条规则截断。旁注-为什么会有限制?你是在与某个古老的COBOL系统交互吗?现在是2013年。s服务器应该比这更聪明。如果服务器有一些限制,那么服务器应该强制执行限制,而不是每个访问它的客户端。@rmaddy在分析系统中,该值被压缩到一个不是用来保存它的字段中。该字段的限制是100个字符。第二个substringToIndex操作可以ld删除冒号。如果其中一个t
      - (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:@":"];  
      }