Splitting NSString into NSArray on component '\n' - iphone

I'm trying to split a NSString into a NSArray, and it's proving difficult even though this is normally an easy task. I'm receiving data, from my Python server and forming a NSString on the iPhone client. I noticed sometimes when I receive multiple messages from my Python server I would NSLog a string like:
Project: textOne
textTwo
After adding the string into a NSArray and calling NSLog on that array the string would show:
Project: (
"textOne\ntextTwo\n"
)
After playing with code:
[str componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
[str componentsSeparatedByString:#"\n"];
[str substringToIndex:[str length]-1];
I have managed to produce NSArray's with content:
Project: (
"textOne",
textTwo
)
And
Project: (
"textOne",
textTwo,
""
)
I cannot produce a NSArray with content:
Project: (
textOne,
textTwo
)
If anyone could help, I'd greatly appreciate it.

Trim your string before separating into components using stringByTrimmingCharactersInSet: to prevent empty components at the end or beginning.
NSCharacterSet *separatorSet = [NSCharacterSet newlineCharacterSet];
NSString *trimmed = [str stringByTrimmingCharactersInSet:separatorSet];
[trimmed componentsSeparatedByCharactersInSet:separatorSet];
This won't prevent empty strings in the middle of your array.
Another solution would be to filter out any undesired strings after separating into components.

Related

remove specific characters from NSString

I wants to remove specific characters or group substring from NSString.
mean
NSString *str = #" hello I am #39;doing Parsing So $#39;I get many symbols in &my response";
I wants remove #39; and $#39; and & (Mostly these three strings comes in response)
output should be : hello I am doing Parsing So i get many symbols in my response
Side Question : I can't write & #39; without space here, because it converted in ' <-- this symbol. so i use $ in place of & in my question.
you should use [str stringByReplacingOccurrencesOfString:#"#39" withString:#""]
or you need replace strings of concrete format like "#number"?
try below code ,i think you got whatever you want simply change the charecterset,
NSString *string = #"hello I am #39;doing Parsing So $#39;I get many symbols in &my response";
NSCharacterSet *trim = [NSCharacterSet characterSetWithCharactersInString:#"#39;$&"];
NSString *result = [[string componentsSeparatedByCharactersInSet:trim] componentsJoinedByString:#""];
NSLog(#"%#", result);

Search for an array of substrings within a string

I want to check whether a string contains any of the substrings that I place in an array. Basically, I want to search the extensions of a file, and if the file is an "image", i want certain code to execute. The only way I can think of categorizing the file as an "Image" without downloading the file is through the substring in a string method. This is my code so far:
NSString *last5Chars = [folderName substringFromIndex: [folderName length] - 5];
NSRange textRangepdf;
textRangepdf =[last5Chars rangeOfString:#"pdf"];
if(textRangepdf.location != NSNotFound)
{
[self.itemType addObject:#"PDF.png"];
}
Is it possible to do this where I can check if last5Chars contains #"jpg" or #"gif" of #"png" etc...?? Thanks for helping!
NSString *fileName;
NSArray *imgExtArray; // put your file extensions in here
BOOL isImage = [imgExtArray containsObject:[fileName pathExtension]];
[folderName hasSuffix:#".jpg"] || [folderName hasSuffix:#".gif"]
obviously you can put it into a loop, if you have a whole arrayful.
Rather than mess about with ranges and suffixes, NSString has a method that treats an NSString as a path and returns an extension, it's called pathExtension.
Have a look in the NSString Documentation
Once you get the extension you can check it against whatever strings you want.

StringByAddingPercentEscapes not working on ampersands, question marks etc

I'm sending a request from my iphone-application, where some of the arguments are text that the user can enter into textboxes. Therefore, I need to HTML-encode them.
Here's the problem I'm running into:
NSLog(#"%#", testText); // Test & ?
testText = [testText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", testText); // Test%20&%20?
As you can see, only the spaces are encoded, making the server disregard everything past the ampersand for the argument.
Is this the advertised behaviour of stringByAddingPercentEscapes? Do I have to manually replace every special character with corresponding hex code?
Thankful for any contributions.
They are not encoded because they are valid URL characters.
The documentation for stringByAddingPercentEscapesUsingEncoding: says
See CFURLCreateStringByAddingPercentEscapes for more complex transformations.
I encode my query string parameters using the following method (added to a NSString category)
- (NSString *)urlEncodedString {
CFStringRef buffer = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)self,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]"),
kCFStringEncodingUTF8);
NSString *result = [NSString stringWithString:(NSString *)buffer];
CFRelease(buffer);
return result;
}

Organize objective-C string for filters

How can I organize this string better for best coding practices. It's a string that defines filters:
NSString* string3 = [[[[[[tvA.text stringByReplacingOccurrencesOfString:#"\n" withString:#" "] stringByReplacingOccurrencesOfString:#"&" withString:#"and"] stringByReplacingOccurrencesOfString:#"garçon" withString:#"garcon"] stringByReplacingOccurrencesOfString:#"Garçon" withString:#"Garcon"] stringByReplacingOccurrencesOfString:#"+" withString:#"and"] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
Is there a way to have it be:
NSString* string3 = [[[[[tvA.text filter1] filter2] filter3] filter4] filter5] stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
You shouldn't be replacing & and + before percent-escaping. The problem is that stringByAddingPercentEscapesUsingEncoding: (IIRC) adds the minimum escapes to make it a "valid" URL string, whereas you want to escape anything that might have a special interpretation. For this, use CFURLCreateStringByAddingPercentEscapes():
return [(NSString*)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)aString, NULL, (CFStringRef)#":/?#[]#!$&'()*+,;=", kCFStringEncodingUTF8) autorelease];
This encodes & and + correctly, instead of just changing them to "and". It also encodes newlines as %0a (so you might want to replace them with spaces; that's your call), and encodes ç as %C3%A7 (which is decoded correctly if you use UTF-8 on the server).
The first thing I'd do is capture the transformation into a method somewhere (where "somewhere" is either an instance method on an appropriate object or a class method on a utility class).
- (NSString *) transformString: (NSString *) aString
{
NSString *transformedString;
transformedString = [aString stringByReplacingOccurrencesOfString:#"\n" withString:#" "];
transformedString = [transformedString stringByReplacingOccurrencesOfString:#"&" withString:#"and"];
transformedString = [transformedString stringByReplacingOccurrencesOfString:#"garçon" withString:#"garcon"];
transformedString = [transformedString stringByReplacingOccurrencesOfString:#"Garçon" withString:#"Garcon"];
transformedString = [transformedString stringByReplacingOccurrencesOfString:#"+" withString:#"and"];
transformedString = [transformedString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
return transformedString;
}
Then:
NSString *result = [myTransformer transformString: tVA.text];
A bit brutish, but it'll work. And by "brutish", I mean that it is going to be slow and will cause a bunch of interim strings to pile up in the autorelease pool. However, if this is something that you only do every now and then, don't worry about it -- while brutish, it is certainly quite straightforward.
If, however, this shows up in performance analysis as a bottleneck, you could first move to using NSMutableString as it has methods for doing replacements in place. That, at least, will reduce memory thrash and will likely be a bit faster in that there is less copying of strings going on.
If that is still too slow, then you will likely need to write yourself a fun little bit of parsing and processing code that walks through the original and copies it to new a new string while also doing any necessary transforms along the way.
But, don't bother optimizing until you prove that it is a problem. And, of course, if it is a problem, you have just one method to optimize!
If performance is not crucial, put the strings and their replacements into an NSDictionary and iterate over the items. Put it all in a helper method and use a NSMutableString to work on it (which reduces at least some of the cost).

How to split a string into sentences cocoa

I have an NSString with a number of sentences, and I'd like to split it into an NSArray of sentences. Has anybody solved this problem before? I found enumerateSubstringsInRange:options:usingBlock: which is able to do it, but it looks like it isn't available on the iPhone (Snow Leopard only). I thought about splitting the string based on periods, but that doesn't seem very robust.
So far my best option seems to be to use RegexKitLite to regex it into an array of sentences. Solutions?
Use CFStringTokenizer. You'll want to create the tokenizer with the kCFStringTokenizerUnitSentence option.
I would use a scanner for it,
NSScanner *sherLock = [NSCanner scannerWithString:yourString]; // autoreleased
NSMutableArray *theArray = [NSMutableArray array]; // autoreleased
while( ![sherLock isAtEnd] ){
NSString *sentence = #"";
// . + a space, your sentences probably will have that, and you
// could try scanning for a newline \n but iam not sure your sentences
// are seperated by it
[sherLock scanUpToString:#". " inToString:&sentence];
[theArray addObject:sentence];
}
This should do it, there could be some little mistakes in it but this is how I would do it.
You should lookup NSScanner in the docs though.. you might come across a method that is
better for this situation.
I haven't used them for a while but I think you can do this with NSString, NSCharacterSet and NSScanner. You create a character set that holds end sentence punctuation and then call -[NSScanner scanUpToCharactersFromSet:intoString:]. Each Scan will suck out a sentence into a string and you keep calling the method until the scanner runs out of string.
Of course, the text has to be well punctuated.
How about:
NSArray *sentences = [string componentsSeparatedByString:#". "];
This will return an array("One","Two","Three") from a string "One. Two. Three."
NSArray *sentences = [astring componentsSeparatedByCharactersInSet:[NSCharacterSet punctuationCharacterSet] ];