How to cut out parts of NSString? - iphone

#"/News/some news text/"
#"/News/some other news text/"
#"/About/Some about text/"
#"/Abcdefg/Some abcdefg text/some more abcdefg text"
How do I cut out the first part of the strings, so that I end up with the following strings?
#"/News/"
#"/News/"
#"/About/"
#"/Abcdefg/"

Use componentsSeparatedByString: to break the string up:
NSArray *components=[string componentsSeparatedByString:#"/"];
if ([components count]>=2) {
// Text after the first slash is second item in the array
return [NSString stringWithFormat:#"/%#/",[components objectAtIndex:1]];
} else {
return nil; // Up to you what happens in this situation
}

If these are pathnames, you may want to look into the path-related methods of NSString, such as pathComponents and pathByDeletingLastPathComponent.
While it's pretty unlikely that the path separator is ever going to change, it's nonetheless a good habit to not rely on such things and use dedicated path-manipulation methods in preference to assuming that the path separator will be a certain character.
EDIT from the year 2013: Or use URLs (more specifically, NS/CFURL objects), which Apple has made pretty clear are the proper way to refer to files from now on, and are necessary for some tasks in a sandbox.

Related

Subscript and Superscripts in CDATA of an xml file. Using UILabel to display the parsed XML contents

I need to display subscripts and superscripts (only arabic numerals) within a UILabel. The data is taken from an XML file. Here is the snippet of XML file:
<text><![CDATA[Hello World X\u00B2 World Hello]]></text>
Its supposed to display X2 (2 as superscript). When I read the string from the NSXMLParser and display it in the UILabel, it displays it as X\u00B2. Any ideas on how to make it work?
I think you can do something like this, assuming the CDATA contents have been read into an NSString and passed into this function:
-(NSString *)removeUnicodeEscapes:(NSString *)stringWithUnicodeEscapes {
unichar codeValue;
NSMutableString *result = [stringWithUnicodeEscapes mutableCopy];
NSRange unicodeLocation = [result rangeOfString:#"\\u"];
while (unicodeLocation.location != NSNotFound) {
// Get the 4-character hex code
NSRange charCodeRange = NSMakeRange(unicodeLocation.location + 2, 4);
NSString *charCode = [result substringWithRange:charCodeRange];
[[NSScanner scannerWithString:charCode] scanHexInt:&codeValue];
// Convert it to an NSString and replace in original string
NSString *unicodeChar = [NSString stringWithFormat:%C", codeValue];
NSRange replacementRange = NSMakeRange(unicodeLocation.location, 6);
[result replaceCharactersInRange:replacementRange withString:unicodeChar];
unicodeLocation = [result rangeOfString:#"\\u"];
}
return result;
}
I haven't had a chance to try this out, but I think the basic approach would work
\u00B2 is not any sort of XML encoding for characters. Apparently your data source has defined their own encoding scheme (which, frankly, is pretty stupid as XML is capable of encoding these directly, using entities outside of CDATA blocks).
In any case, you'll have to write your own parser that handles \u#### and converts that to the correct character.
I asked the question to my colleague and he gave me a nice and simple workaround. Am describing it here, in case others also get stuck at this.
Firstly goto this link. It has a list of all subscripts and superscripts. For example, in my case, I clicked on "superscript 0". In the following HTML page detailing "superscript 0", goto "Java Data" section and copy the "⁰". You can either place this directly in XML or write a simple regex in obj-c to replace \u00B2 with "⁰". And you will get nice X⁰. Do the same fro anyother superscript or subscript that you might want to display.

Objective-C: Comparing normal strings and strings found in NSMutableArrays

I am confused about strings (a beginner's problem, I'm afraid):
I have one NSMutableArray called Notebook. At index position 1, I have an object, which I think is a string. At least I put it into the array like this:
[NoteBook replaceObjectAtIndex:1 withObject:#"x-x-x-x"];
So far so good. If I put this into an UILabel, it will show x-x-x-x on my screen. The nightmare starts when I try to compare this string with other strings. Let's consider that I do not want to display the string x-x-x-x on my screen, but just to have a blank instead. So I thought I could achieve this by coding this:
NSString *tempDateString;
tempDateString = [NSString stringWithFormat:#"%#",[NoteBook objectAtIndex:1]];
if (tempDateString == #"x-x-x-x") {
UISampleLabel.text = #"";
}
For some reason, this does not work, i.e. even if the string at position 1 of my array is 'x-x-x-x', it will still not set my UISampleLabel to nothing.
I suppose that I am getting confused with the #"" markers. When do I really need them? Why can't I simply code tempDateString = [NoteBook objectAtIndex:1]; without the formatting thing?
Any help and suggestions would be very much appreciated!
You need to compare string with isEqualToString:
if ([tempDateString isEqualToString:#"x-x-x-x"]) {
UISampleLabel.text = #"";
}
In addition to the question that's been answered:
Why can't I simply code tempDateString = [NoteBook objectAtIndex:1]; without the formatting thing?
You can. Why do you think you can't?

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] ];

RTL shows numbers at the end of lines

Trying to display a hebrew string that starts with a number, always displays the number at the end of the string like so: 1. יום שישי בבוקר
but I need the number to be displayed at the right side of the text-
any solution to that?
It happens with UILabel & UITextField & UITextView
and trying to write the number at the left side also produce the same resault.
Playing with combinations of UITextAlignment will doesn't help.
You don't need to change any setting on UILabel, just put the character with unicode 0x200F before your string. This is the reason:
In Unicode many characters have a specific directionality, which lets the system know it has to be written, say LTR, like سلام. The paragraph usually uses the direction of its first character. That's why your string without the number is typed from right to left automatically.
Now some characters, like numbers, have "weak" directionality, so they basically take that of their surrounding. When you type "1. בבוקר", the system first sees 1, so takes the usual LTR direction. Changing the alignment won't help, as it just shifts the whole text to right, or center.
To solve this issue, Unicode has two marker characters (LTR: 0x200E, RTL:200F). These are invisible, but dictate the directionality. So while "1. בבוקר" is...
בבוקר
if you type "#x200F" + "1. בבוקר" it will display like this:
‏1. בבוקר
Building on Mo's great answer:
This is the code Obj-C:
NSString *RTFstr = "1. בבוקר"; //This could be any right-to-left string
NSString *directionalString = [#"\u200F" stringByAppendingString:[note text]];
[someUITextView setString:directionalString];
And it actually works...
I had a slightly different problem but Mo's answer gave me the clue.
I wanted to get a LTR text (like "abcd") displayed in RTL direction ("dcba") without having to do myself the string reversing. Turns out enclosing the string between \u202E and \u202C does the trick.
I also recommend reading the following page as it gives a very good explanation of all these unicode magic:
http://www.iamcal.com/understanding-bidirectional-text/
Swift anybody?
extension String {
func stringByForcingWritingDirectionLTR() -> String {
return "\u{200E}".stringByAppendingString(self)
}
func stringByForcingWritingDirectionRTL() -> String {
return "\u{200F}".stringByAppendingString(self)
}
}
not sure if there's fancier way to do this but you might want to try something like this:
NSString *test = #"12. just a teststring";
NSString *number = [test substringToIndex: [test rangeOfString: #" "].location];
NSString *text = [test substringFromIndex: [test rangeOfString: #" "].location];
test = [NSString stringWithFormat: #"%# %#", text, number];
// test == "just a teststring 12."

Finding a string in a string

Does anyone know a nice efficient way of finding a string within a string (if it exists) in objective c for iPhone Development, I need to find the part of the string in between two words, e.g. here I need to find the co2 rating number in the string, where z is the value I'm looking for ...
xxxxxco_2zendxxxxxxx
Ideally, I'd use a regular expression for this, probably something like co_2(.*?)end, so I'd take a look at RegexKitLite as stimms suggests.
If that is not suitable, you could extract the string you're looking for with something like this:
NSString* src = #"xxxxxco_2zendxxxxxxx";
NSRange startMarker = [src rangeOfString:#"co_2"];
if (startMarker.location != NSNotFound) {
NSScanner* scanner = [NSScanner scannerWithString:src];
[scanner setScanLocation:startMarker.location + startMarker.length];
NSString* co2Value = #"";
[scanner scanUpToString:#"end" intoString:&co2Value];
NSLog(#"co_2 value is %#", co2Value);
} else {
NSLog(#"co_2 marker not found");
}
Here we look for #"co_2", failing if it's not found, then use an NSScanner to grab everything from just after that string to the next occurrence of #"end". Note that if #"end" is missing this code will silently grab the rest of the string.
This might be of interest to you (in particular the rangeOfString function):
(NSRange)rangeOfString:(NSString *)aString
Unfortunately Cocoa doesn't have any built-in RegEx support..
String matching is a well explored domain especially for algorithms dealing with genetic material. You could check out the Art of Computer programming for 10x more than you ever wanted to know about string matching.
Most of that is overkill and you would be fine using a regular expression. Check out http://regexkit.sourceforge.net/RegexKitLite/ a regex library which runs on the iphone.