Разбор большой NSString

У меня есть большой объект NSString, как показано ниже. Я хочу проанализировать эту строку, чтобы получить все значения icmp_seq и времени в ней. Код, который я написал, всегда дает мне последнее значение.

Любая идея, как сделать это лучше, кроме как разбить его на символ новой строки, а затем запустить синтаксический анализатор для каждого разделения.

64 bytes from 74.125.129.105: icmp_seq=0 ttl=43 time=23.274 ms
64 bytes from 74.125.129.105: icmp_seq=1 ttl=43 time=28.704 ms
64 bytes from 74.125.129.105: icmp_seq=2 ttl=43 time=23.519 ms
64 bytes from 74.125.129.105: icmp_seq=3 ttl=43 time=23.548 ms
64 bytes from 74.125.129.105: icmp_seq=4 ttl=43 time=23.517 ms
64 bytes from 74.125.129.105: icmp_seq=5 ttl=43 time=23.293 ms
64 bytes from 74.125.129.105: icmp_seq=6 ttl=43 time=23.464 ms
64 bytes from 74.125.129.105: icmp_seq=7 ttl=43 time=23.323 ms
64 bytes from 74.125.129.105: icmp_seq=8 ttl=43 time=23.451 ms
64 bytes from 74.125.129.105: icmp_seq=9 ttl=43 time=23.560 ms

Код:

-(void)parsePingData:(NSString *)iData {
  NSRange anIcmpRange = [iData rangeOfString:@"icmp_seq"];
  NSRange aTtlRange =[iData rangeOfString:@"ttl"];
  NSRange icmpDataRange = NSMakeRange(anIcmpRange.location + 1, aTtlRange.location - (anIcmpRange.location + 1));
  NSLog(@"Output=%@",[iData substringWithRange:icmpDataRange]);    
}

person Abhinav    schedule 30.01.2013    source источник
comment
Я не думаю, что есть что-то, что даст вам массив. Вам придется перебирать записи самостоятельно. Если он ДЕЙСТВИТЕЛЬНО большой, может быть целесообразно просмотреть строку, а не разбивать ее, но это довольно прямолинейно — в строке есть только один :, так что это хороший символ для поиска.   -  person Hot Licks    schedule 31.01.2013
comment
Рассматривали ли вы возможность использования NSScanner или NSRegularExpression?   -  person Peter Hosey    schedule 31.01.2013


Ответы (2)


На основе кода, который вы разместили с некоторыми изменениями, мы можем получить что-то вроде этого:

NSRange range = NSMakeRange(0, largeString.length);
while (range.location != NSNotFound) {
  NSRange icmpRange = [largeString rangeOfString:@"icmp_seq=" options:NSLiteralSearch range:range];
  range.location = icmpRange.location + icmpRange.length;
  range.length = largeString.length - range.location;
  if (range.location != NSNotFound) {
    NSRange ttlRange = [largeString rangeOfString:@" ttl" options:NSLiteralSearch range:range];
    if (ttlRange.location != NSNotFound) {
      NSLog(@"icmp_seq = [%@]", [largeString substringWithRange:NSMakeRange(range.location, ttlRange.location - range.location)]);
    }
  }
}

Сохраняя обновленный диапазон и используя rangeOfString:options:range, мы можем искать только в той части строки, в которой мы еще не искали.

person pldoverflow    schedule 31.01.2013

Вот как это сделать. Я уверен, что есть лучшее решение, так что извините, если это кажется действительно плохим. Но вы могли бы сделать:

NSArray *stringArray = [largeString componentsSeparatedByString: @":"];

Затем выполните цикл for:

for (int i = 1; i < stringArray.count; i++) {
     [self parsePingData:[stringArray objectAtIndex:i]];
}

Я начал это с int i = 1, потому что индекс 0 не будет содержать нужных вам значений.

person Firo    schedule 30.01.2013
comment
Да, но что вы делаете, когда начинаете пинговать адреса ipv6, в которых уже есть :? Похоже, это могло бы использовать некоторые улучшения ... - person Richard J. Ross III; 31.01.2013
comment
Действительно, я исходил из комментария Hot Licks. Я оглядываюсь и вижу, есть ли лучшее решение. - person Firo; 31.01.2013
comment
Вы можете использовать что-то еще, что вы считаете уникальным. Вроде байты из. Опять же, это решение кажется странным/плохим обходным путем, но оно может сработать. - person Firo; 31.01.2013