I am trying to parse a string with a format like this:
*date1:
- band1.1 # venue1.1.
- band1.2 # venue1.2.
*date2:
- band 2.1 # venue2.1.
- band 2.2 # venue2.2.
etc
The number of dates and the number of bands and the associated venue can vary. I am using code based on the example at the bottom of this page.
I am using this snippet of code (I left out the bits at the bottom as they are irrelevant, but yes, I do close the loops etc.):
NSScanner *scanner1 = [NSScanner scannerWithString:contents];
NSCharacterSet *colon = [NSCharacterSet characterSetWithCharactersInString:#":"];
NSCharacterSet *at = [NSCharacterSet characterSetWithCharactersInString:#"#"];
NSCharacterSet *dot = [NSCharacterSet characterSetWithCharactersInString:#"."];
NSLog(#"scanner starting");
while ([scanner1 isAtEnd] == NO) {
if ([scanner1 scanString:#"*" intoString:NULL] && [scanner1 scanUpToCharactersFromSet:colon intoString:&tempDate] && [scanner1 scanString:#":" intoString:NULL])
{
NSLog(#"%#", tempDate);
if ([scanner1 scanString:#"-" intoString:NULL] && [scanner1 scanUpToCharactersFromSet:at intoString:&tempBands] && [scanner1 scanString:#"#" intoString:NULL] && [scanner1 scanUpToCharactersFromSet:dot intoString:&tempVenue]
&&[scanner1 scanString:#"." intoString:NULL])
{
NSLog(#"%# %#", tempBands, tempVenue);
}
}
} NSLog(#"ended scanning");
Currently, the first date is parsed and printed to the console, and the first venue and band of that date are printed. "ended scanning" is never printed. I have been battling this for hours and I am unsure of what to do now. I have a feeling that I do not understand the inner workings of NSScanner and there is probably a different way to tackle this problem. Maybe I need a second scanner?
After the first round of the while loop, the scanner's position is right after "venue1.". The next round of the loop starts with scanning an asterisk, which fails (returns NO) because the next (non-whitespace) character is a dash. Therefore, the body of the if statement isn't executed and the scanner's position is not advanced any further, resulting in an infinite loop.
Related
I have a UITextField called textfield. And I have this code to check if the text in the textfield is equal to "exampletext"
if ([textfield.text isEqualToString:#"exampletext"]) {
NSLog(#"Correct");
} else {
NSLog(#"Wrong");
}
But I also want to check if the text in the textfield is almost equal to "exampletext", if the text is almost the same as "exampletext". Like if the text was "eampletex" I want to NSLog(#"Close")
Are there any ways to check if the textfield text is like 50% equal to "exampletext"?
Or any ways to check if the textfield text has 50% the same characters as "exampletext"?
Or something else like that?
What you are looking for is an implementation of the levenshtein distance, levenshtein("hello", "hallo") => 1, levenshtein("hello", "ellos") => 2. You can check this library.
Once you have the distance between the two strings, you could get it as a percentage calculating: percentage = 100 * levenshtein(original,other) / length(original)
Here's my go at it. Create a custom character set from the string you want to match. Check each character in the texfield.text against that character set, and if the number of matches is close to the number of letters in the string, do something..
NSString *testString = #"wordToCompare";
NSString *textFromTextfield = textfield.text;
//create a custom character set from the word you want to compare to...
NSCharacterSet *characterSetForString = [NSCharacterSet characterSetWithCharactersInString:testString];
//keep track of how many matches...
int numberOfCharsThatMatchSet = 0;
for (int x = 0; x < [textFromTextField length]; x++) {
unichar charToCheck = [textFromTextField characterAtIndex:x];
if ([characterSetForString characterIsMember:charToCheck] == YES) {
numberOfCharsThatMatchSet++;
}
NSLog(#"%d", numberOfCharsThatMatchSet);
}
// if the number of matches is the same as the length of the word + or - 2...
if ((numberOfCharsThatMatchSet > [testString length] - 2 ) && (numberOfCharsThatMatchSet < [testString length] + 2 )) {
NSLog(#"close match...");
}
Not sure if this is 100% what you're looking for, but maybe it will help anyway...
I'm sure there might be some open source out there somewhere that would do this for you..however, one approach I can think of that will give you a bit of a lead...
Sort out the characters of both your strings into arrays. Determine which string you want to be the master string and grab the string length of it.
Now compare each character. Ex: Word 1: hello, Word 2: ello.
Each time a letter is found add one to a count. If by the end of your looping your count is 80% of the original length you grabbed from the master string or greater then you most likely have a partial match.
So for our example Word 1 will be our master string and its length is 5. "ello" contains 4/5 characters and therefore is matches 80% of the original string.
I don't think there is an easy way (with several lines of code) of solving this. There are several algorithms you might consider and pick the one which suits your needs most.
You should look at this question. Although it has been designed and answered for another language, you asked for a way or method so you have your solution there.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Remove HTML Tags from an NSString on the iPhone
I am using google direction api to display map in my mapview and it gives me HTML direction string ,that contain HTML tags.
Now i want to display that string in plain text how can i do that.My strings are here :
Head <b>southwest</b> toward <b>GH Rd</b>
Exit the roundabout onto <b>GH Rd</b><div style="font-size:0.9em">Go through 1 roundabout</div>
At the roundabout, take the <b>1st</b> exit onto <b>Road Number 2</b><div style="font-size:0.9em">Pass by myonlinesearch.blogspot.com (on the left in 600 m)</div>
At the roundabout, take the <b>3rd</b> exit onto <b>CH Rd</b>
At <b>Indroda Cir</b>, take the <b>2nd</b> exit onto <b>Gandhinagar Ahmedabad Rd/SH 71</b><div style="font-size:0.9em">Continue to follow Gandhinagar Ahmedabad Rd</div><div style="font-size:0.9em">Go through 1 roundabout</div>
At the roundabout, take the <b>1st</b> exit onto <b>Sardar Patel Ring Rd</b>
At <b>Ranasan Cir</b>, take the <b>3rd</b> exit onto <b>NH 8</b><div style="font-size:0.9em">Pass by Galaxy Restaurant (on the left in 4.3 km)</div>
Turn <b>left</b> onto <b>Galaxy Rd</b><div style="font-size:0.9em">Pass by Shiv Shakti Food Fort (on the left)</div>
Turn <b>left</b> onto <b>NH 59</b>
Turn <b>right</b><div style="font-size:0.9em">Go through 1 roundabout</div>
Turn <b>right</b>
Turn <b>left</b><div style="font-size:0.9em">Destination will be on the right</div>
You can use RegularExpression/Predicates to remove all characters between < & >.
But if your text contains some <> it will be removed
NSRange range;
NSString *string;
while ((range = [string rangeOfString:#"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound){
string=[string stringByReplacingCharactersInRange:range withString:#""];
}
NSLog(#"Un block string : %#",string);
You will have to parse the text via a parser it is very easy to parse these text just scan the line and use replace function there.
[yourString stringByReplacingOccurrencesOfString:#"<b>"withString:""];
[yourString stringByReplacingOccurrencesOfString:#"</b>"withString:""];
This will do the trick for you.
Either you can go with..
-(NSString *) stringByStrippingHTML
{
NSRange r;
NSString *s = [[self copy] autorelease];
while ((r = [s rangeOfString:#"]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:#""];
return s;
}
Or better use NSString category to remove HTML from your string i.e. "GTMNSStringHTMLAdditions".
I'm looking for a way to search an arbitrary long string (10000 characters) and find the number of times a specific keyword is repeated in the string. How can this be done?
I have this method, that pretty much counts the number of fragments left after the string is split around keywords, but it is not case insensitive.
-(void)countKeywords
{
NSArray* components = [self.salesCopy componentsSeparatedByString:#"search term"];
NSLog(#"search term number found: %i",components.count);
}
What's a better way to count the number of keywords within a string?
Splitting the string, counting parts, and throwing them away is not efficient. Searching for substring repeatedly without creating new objects would definitely be more efficient. Since the string is relatively long, you may benefit from implementing an advanced string search algorithm, for example Knuth-Morris-Pratt, to significantly decrease your search time.
Here is an implementation that should be faster than your splitting code:
NSString *str = #"Hello sun, hello bird, hello my lady! Hello breakfast, May I buy you again tomorrow?";
NSRange r = NSMakeRange(0, str.length);
int count = 0;
for (;;) {
r = [str rangeOfString:#"hello" options:NSCaseInsensitiveSearch range:r];
if (r.location == NSNotFound) {
break;
}
count++;
r.location++;
r.length = str.length - r.location;
}
NSLog(#"%d", count);
Just create copies of both self.salesCopy and the searchTerm, set the copies to lower case via [NSString lowercaseString], then perform your code, and you'll have the count
-(void)countKeywords
{
NSString *lowerCaseSalesCopy = [self.salesCopy lowercaseString];
NSString *lowerCaseSearchTerm = [searchTerm lowercaseString];
NSArray* components = [lowerCaseSalesCopy componentsSeparatedByString:lowerCaseSearchTerm];
NSLog(#"search term number found: %i",components.count);
}
I am not 100% sure that could help you, but may do some of the job you need (if not all):
NSRange ran = [yourString rangeOfString:wordToLookFor options:NSCaseInsensitiveSearch];
And look at
ran.length
ran.location
ran.location will provide you the location within the string of the first occurrence. You could then cut the string after this occurrence, and run this again until the end of the string.
I'm making a word game and I've finally come up to one of the most important parts of my game, the compare part.
I got this label which will be invisible when it launches with the word that has to be guessed displaying in it with a random word generator. For example the word is: GARAGE
Now, for my game I have to compare the word with the input now I've already done this with the entire word with NSString but I want it to compare every letter. I want to be able to show that if the input has G as the first letter aswell, like garage. I want it to do something.
I want to know if this is possible and which methods you would use. I was thinking about making 6 strings since all my random words have 6 letters, and then break the word to 6 strings and the input aswell and then compare strings?
Hope someone has some usefull tips or example code thanks
So, assuming your string to be guessed...
NSString *stringToGuess = #"GARAGE";
and you were checking to see if it started with "GA"
NSString *myString = #"GA";
you would check it with hasPrefix:
if ([stringToGuess hasPrefix:myString]) {
// <stringToGuess> starts with <myString>
}
The documentation for NSString describes lots of neat methods for just about anything string related.
hasPrefix will let you tell if one string begins with another string. There's also characterAtIndex. You could use that to get one character from each string and compare it to the other.
You could write a method that would take an integer index and compare the two strings at that index:
- (BOOL) compareStringOne: (NSString *) stringOne
toStringTwo: (NSString *) stringTwo
atIndex: (NSUInteger) index;
{
if ([stringOne length] < index+1 || [stringTwo length] < index+1)
return FALSE;
return [stringOne characterAtIndex: index] == [stringTwo characterAtIndex: index];
}
i would like to fetch a part of a string in objective C:
a sampletext:
This is the story of a startnew mountainend. There were many bluestart green houses end.........
the function should return a array of strings which are all in between the "start" and the "end".
How can i write this in objective C?
Andreas
I think what you want is something like this.
NSString *text = nil;
NSScanner *theScanner = [NSScanner scannerWithString:#"This is the story of a startnew mountainend. There were many bluestart green houses end"];
[theScanner scanUpToString:#"start" intoString:NULL] ;
[theScanner scanUpToString:#"end" intoString:&text] ;
Of course there are several edge cases you should watch out for like what if you reach the end of the string without find "end"? What if there is a "start" after you already found the word "start" before you find an "end"? Anyways, hopefully this points you in the right direction.