Contraer secuencias de espacios en blanco en un solo carácter y cadena de recorte

Considere el siguiente ejemplo:

" Hello this is a long string! " 

Quiero convertir eso en:

 "Hello this is a long string!" 

OS X 10.7+ e iOS 3.2+

Use la solución de expresión regular nativa provista por hfossli.

De otra manera

Use su biblioteca de expresiones regulares favorita o use la siguiente solución nativa de Cocoa:

 NSString *theString = @" Hello this is a long string! "; NSCharacterSet *whitespaces = [NSCharacterSet whitespaceCharacterSet]; NSPredicate *noEmptyStrings = [NSPredicate predicateWithFormat:@"SELF != ''"]; NSArray *parts = [theString componentsSeparatedByCharactersInSet:whitespaces]; NSArray *filteredArray = [parts filteredArrayUsingPredicate:noEmptyStrings]; theString = [filteredArray componentsJoinedByString:@" "]; 

Regex y NSCharacterSet está aquí para ayudarlo. Esta solución recorta espacios en blanco iniciales y finales, así como múltiples espacios en blanco.

 NSString *original = @" Hello this is a long string! "; NSString *squashed = [original stringByReplacingOccurrencesOfString:@"[ ]+" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, original.length)]; NSString *final = [squashed stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

Logging final da

 "Hello this is a long string!" 

Posibles patrones regex alternativos:

  • Reemplazar solo espacio: [ ]+
  • Reemplazar espacio y tabs: [ \\t]+
  • Reemplazar espacio, tabs y saltos de línea: \\s+

Resumen de rendimiento

  • Esta solución: 7.6 segundos
  • Dividir, filtrar, unir (Georg Schölly) : 13.7 segundos

La facilidad de extensión, rendimiento, líneas numéricas de código y la cantidad de objetos creados hace que esta solución sea apropiada.

En realidad, hay una solución muy simple para eso:

 NSString *string = @" spaces in front and at the end "; NSString *trimmedString = [string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSLog(@"%@", trimmedString) 

( Fuente )

Con una expresión regular, pero sin la necesidad de ningún marco externo:

 NSString *theString = @" Hello this is a long string! "; theString = [theString stringByReplacingOccurrencesOfString:@" +" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, theString.length)]; 

Una solución de una línea:

 NSString *whitespaceString = @" String with whitespaces "; NSString *trimmedString = [whitespaceString stringByReplacingOccurrencesOfString:@" " withString:@""]; 

Esto debería hacerlo …

 NSString *s = @"this is a string with lots of white space"; NSArray *comps = [s componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSMutableArray *words = [NSMutableArray array]; for(NSString *comp in comps) { if([comp length] > 1)) { [words addObject:comp]; } } NSString *result = [words componentsJoinedByString:@" "]; 

Otra opción para regex es RegexKitLite , que es muy fácil de integrar en un proyecto de iPhone:

 [theString stringByReplacingOccurencesOfRegex:@" +" withString:@" "]; 

Prueba esto

 NSString *theString = @" Hello this is a long string! "; while ([theString rangeOfString:@" "].location != NSNotFound) { theString = [theString stringByReplacingOccurrencesOfString:@" " withString:@" "]; } 

Aquí hay un fragmento de una extensión de NSString , donde "self" es la instancia de NSString . Puede usarse para colapsar espacios en blanco contiguos en un espacio simple al pasar en [NSCharacterSet whitespaceAndNewlineCharacterSet] y ' ' a los dos argumentos.

 - (NSString *) stringCollapsingCharacterSet: (NSCharacterSet *) characterSet toCharacter: (unichar) ch { int fullLength = [self length]; int length = 0; unichar *newString = malloc(sizeof(unichar) * (fullLength + 1)); BOOL isInCharset = NO; for (int i = 0; i < fullLength; i++) { unichar thisChar = [self characterAtIndex: i]; if ([characterSet characterIsMember: thisChar]) { isInCharset = YES; } else { if (isInCharset) { newString[length++] = ch; } newString[length++] = thisChar; isInCharset = NO; } } newString[length] = '\0'; NSString *result = [NSString stringWithCharacters: newString length: length]; free(newString); return result; } 

Solución alternativa: obtén una copia de OgreKit (la biblioteca de expresiones regulares de Cocoa).

  • OgreKit (página web japonesa – el código está en inglés)
  • OgreKit ( traducción automática de Google):

Toda la función es entonces:

 NSString *theStringTrimmed = [theString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString:@"\s+"]; return [regex replaceAllMatchesInString:theStringTrimmed withString:@" "]); 

Corto y dulce.

Si NSScanner la solución más rápida, una serie de instrucciones cuidadosamente construidas usando NSScanner probablemente funcionaría mejor, pero eso solo sería necesario si planea procesar bloques de texto enormes (muchos megabytes).

según @Mathieu Godart es la mejor respuesta, pero falta una línea, todas las respuestas solo reducen el espacio entre las palabras, pero cuando tienen tabs o tienen una pestaña en el espacio, así: “esto es texto \ t, y \ tTab entre, y así sucesivamente “en el código de tres líneas: la cadena que queremos reducir los espacios en blanco

 NSString * str_aLine = @" this is text \t , and\tTab between , so on "; // replace tabs to space str_aLine = [str_aLine stringByReplacingOccurrencesOfString:@"\t" withString:@" "]; // reduce spaces to one space str_aLine = [str_aLine stringByReplacingOccurrencesOfString:@" +" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, str_aLine.length)]; // trim begin and end from white spaces str_aLine = [str_aLine stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

el resultado es

 "this is text , and Tab between , so on" 

sin reemplazar la pestaña, el resultado será:

 "this is text , and Tab between , so on" 

También puede usar un argumento simple mientras. No hay magia RegEx allí, así que tal vez sea más fácil de entender y alterar en el futuro:

 while([yourNSStringObject replaceOccurrencesOfString:@" " withString:@" " options:0 range:NSMakeRange(0, [yourNSStringObject length])] > 0); 

Seguir dos expresiones regulares funcionaría según los requisitos

  1. @ “+” para hacer coincidir espacios en blanco y tabs
  2. @ “\\ s {2,}” para hacer coincidir espacios en blanco, tabs y saltos de línea

A continuación, aplique el método de instancia de stringByReplacingOccurrencesOfString:withString:options:range: para reemplazarlos con un espacio en blanco único.

p.ej

 [string stringByReplacingOccurrencesOfString:regex withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, [string length])]; 

Nota: No utilicé la biblioteca ‘RegexKitLite’ para la funcionalidad anterior para iOS 5.xy superior.