Search tags in string - objective-c

I have a string, and I want to search words (tags) that begin with "#" and end with "." or "," or " " I found this online, but is limited because:
- You can find a single word in the string (although there are more words)
- "RangeOfString" does not allow multiple choices
NSString *stringText = #"test #hello #world";
NSString *result = nil;
// Determine "#"
NSRange hashRange = [stringText rangeOfString:#"#" options:NSCaseInsensitiveSearch];
if (hashRange.location != NSNotFound)
{
// Determine " " location according to "#" location
NSRange endHashRange;
endHashRange.location = hashRange.length + hashRange.location;
endHashRange.length = [stringText length] - endHashRange.location;
endHashRange = [stringText rangeOfString:#" " options:NSCaseInsensitiveSearch range:endHashRange];
if (endHashRange.location != NSNotFound)
{
// Tags found: retrieve string between them
hashRange.location += hashRange.length;
hashRange.length = endHashRange.location - hashRange.location;
result = [stringText substringWithRange:hashRange];
}
}
you have idea how can I do?
Thank you!

You can use NSRegularExpression class, like this:
NSError *error = NULL;
NSRegularExpression *tags = [NSRegularExpression
regularExpressionWithPattern:#"[#]([^, .]+)([, .]|$)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *matches = [tags matchesInString:str options:0 range:NSMakeRange(0, str.length)];
for (NSTextCheckingResult *match in matches) {
NSLog(#"%#", [str substringWithRange:[match rangeAtIndex:1]]);
}
You may need to play with your regular expression to get it just right. The reference that I liked describes the grammar of the regex language supported by Apple's classes.

You should use NSRegularExpression, which will give you multiple matches.
The following is an untested example:
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\b(#\\S*[.,])\\b" options:NSRegularExpressionCaseInsensitive];
int numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, string.length)];
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];

You will most likely want to use NSScanner.
NSString *stringText = #"test #hello #world";
NSString *result = nil;
NSCharacterSet *endingChars = [NSCharacterSet characterSetWithCharactersInString:#"., "];
NSScanner *scanner = [NSScanner scannerWithString:stringText];
scanner.charactersToBeSkipped = nil;
[scanner scanUpToString:#"#" intoString:NULL];
[scanner scanString:#"#" intoString:NULL];
[scanner scanUpToCharactersFromSet:endingChars intoString:&result];
[scanner scanCharactersFromSet:endingChars intoString:NULL];
STAssertEqualObjects(result, #"hello", nil);
At that point you just loop until [scanner isAtEnd];
NSString *stringText = #"test #hello #world";
NSString *match = nil;
NSMutableArray *results = [NSMutableArray arrayWithCapacity:2];
NSCharacterSet *endingChars = [NSCharacterSet characterSetWithCharactersInString:#"., "];
NSScanner *scanner = [NSScanner scannerWithString:stringText];
scanner.charactersToBeSkipped = nil;
while (![scanner isAtEnd]) {
[scanner scanUpToString:#"#" intoString:NULL];
[scanner scanString:#"#" intoString:NULL];
[scanner scanUpToCharactersFromSet:endingChars intoString:&match];
[scanner scanCharactersFromSet:endingChars intoString:NULL];
[results addObject:match];
}
STAssertEquals(results.count, 2, nil);
STAssertEqualObjects([results objectAtIndex:0], #"hello", nil);
STAssertEqualObjects([results objectAtIndex:1], #"world", nil);

Related

Parsing an NSString to find and increment numeric values

I have an string value.
NSString *getAllData = #"0,testing,u,4,u";
Now I want to increment in all the numeric values in the string e.g. #"1,testing,u,5,u"
How can this be done?
Here is your answer...
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *getAllData = #"0,testing,u,4,u";
NSMutableArray *resultArray = [NSMutableArray array];
[[getAllData componentsSeparatedByString:#","] enumerateObjectsUsingBlock:^(NSString *subString, NSUInteger idx, BOOL *stop) {
if([self isNumeric:subString])
{
[resultArray addObject:[NSString stringWithFormat:#"%d", [subString intValue] + 1]];
}
else [resultArray addObject:subString];
}];
NSString *finalOutput = [resultArray componentsJoinedByString:#","];
NSLog(#"%#", finalOutput);
}
- (BOOL)isNumeric:(NSString *)aString
{
NSString *expression = [NSString stringWithFormat:#"^[0-9]*$"];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:nil];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:aString options:0 range:NSMakeRange(0, [aString length])];
return (numberOfMatches != 0);
}
You can use the NSScanner class to find the numbers in the string, and convert them to integers. The NSMutableString class can be used to accumulate the output string.
- (NSString *)incrementValuesInString:(NSString *)input
{
NSScanner *scanner = [NSScanner scannerWithString:input];
[scanner setCharactersToBeSkipped:nil];
NSMutableString *result = [NSMutableString string];
while ( ![scanner isAtEnd] )
{
// copy characters to the result string until a digit is found
NSString *temp;
if ( [scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&temp] )
[result appendString:temp];
// scan the number and increment it
if ( ![scanner isAtEnd] )
{
int value;
if ( [scanner scanInt:&value] )
[result appendFormat:#"%d", value + 1];
}
}
return( [result copy] );
}

Printing particular value from NSString

NSDictionary* headers; = [(NSHTTPURLResponse *)response allHeaderFields];
NSString *str;= [headers objectForKey:#"Www-Authenticate"];
NSLog(#"value:%#",str);
value:First aid="my server part", qop="accept", nonce="nyeraAT567WE"
I want to get and print only nonce
You need a regex to extract it:
NSError *error=nil;
NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:#"nonce=\"(.*)\"" options:0 error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
NSString *nonce = [str substringWithRange:[match rangeAtIndex:1]];
NSLog(#"%#",nonce);

how to fetch the string starts with &abc and ends with &

i like to know how to fetch the specific string which starts with &abc and ends with &. I tried with had prefix and sufix . but this is not new line ,
&xyz;123:183:184:142&
&abc;134:534:435:432&
&qwe;323:535:234:532&
my code :
NSMutableArray *substrings = [NSMutableArray new];
NSScanner *scanner = [NSScanner scannerWithString:s];
[scanner scanUpToString:#"&abc" intoString:nil]; //
NSString *substring = nil;
[scanner scanString:#"&abc" intoString:nil]; // Scan the # character
if([scanner scanUpToString:#"&" intoString:&substring]) {
// If the space immediately followed the &, this will be skipped
[substrings addObject:substring];
NSLog(#"substring is :%#",substring);
}
// do something with substrings
[substrings release];
how to make "scanner scanUpToString:#"&abc" and count ":"==3 till "#"???? can help me
NSArray *arr = [NSArray arrayWithObjects:#"&xyz;123:183:184:142&",
#"&abc;134:534:435:432&",
#"&qwe;323:535:234:532&",
#"& I am not in it",
#"&abc I am out &" ,nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self BEGINSWITH[cd] %# AND self ENDSWITH[cd] %#",#"&abc",#"&"];
NSLog(#"Sorted Array %#",[arr filteredArrayUsingPredicate:predicate]);
NSArray *sortedArray = [arr filteredArrayUsingPredicate:predicate];
NSMutableArray *finalResult = [NSMutableArray arrayWithCapacity:0];
for(NSString *string in sortedArray)
{
NSString *content = string;
NSRange range1 = [content rangeOfString:#"&abc"];
if(range1.length > 0)
content = [content stringByReplacingCharactersInRange:range1 withString:#""];
NSRange range2 = [content rangeOfString:#"&"];
if(range2.length > 0)
content = [content stringByReplacingCharactersInRange:range2 withString:#""];
[finalResult addObject:content];
}
NSLog(#"%#",finalResult);
Try using NSRegularExpression:
- (BOOL)isValidString:(NSString *)string
{
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:#"^&abc.*&$" options:0 error:NULL];
NSTextCheckingResult *result = [regularExpression firstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
return (result != nil);
}

How to remove the content before '>' and after space in objective C?

Here is the example:
<aNodeName thsisjijdsnjdnjsd>, and I would like to remove thsisjijdsnjdnjsd,
How can I detect the string which is before the > and after the space , and trim out it in objective C? Also, please remind that I don't know the aNodeName or thsisjijdsnjdnjsd, because the data may turn out something like this:
<anotherNodeName zxzxxzxzxz>, and I need to remove zxzxxzxzxz.
Basically you have two options
Regular expressions
NSString *string = #"<aNodee thsisjijdsnjdnjsd>";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"<(\\S+)( .*)>" options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
[matches enumerateObjectsUsingBlock:^(NSTextCheckingResult *result, NSUInteger idx, BOOL *stop) {
NSString* nodeName = [string substringWithRange:[result rangeAtIndex:1]];
NSString* value = [string substringWithRange:[result rangeAtIndex:2]];
NSLog(#"%# %#",nodeName, value);
}];
Note, that you shouldn't parse complex html with Regular Expressions.
NSScanner
NSScanner *scanner = [NSScanner scannerWithString:string];
BOOL recordingValue = NO;
NSMutableString *valueString = [#"" mutableCopy];
[scanner setScanLocation:0];
while (![scanner isAtEnd]) {
NSString *charAtlocation = [string substringWithRange:NSMakeRange([scanner scanLocation], 1)];
if ([charAtlocation isEqualToString:#" "]){
recordingValue = YES;
[valueString appendString:#" "];
} else{
if ([charAtlocation isEqualToString:#">"]){
recordingValue = NO;
} else if (recordingValue) {
[valueString appendString:charAtlocation];
}
}
[scanner setScanLocation:[scanner scanLocation]+1];
} ;
NSLog(#"Scanner approach: %#", valueString);
NSLog(#"Scanner approach: %#", [string stringByReplacingOccurrencesOfString:valueString withString:#""]);
Complete command line based example
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSString *string = #"<aNodee thsisjijdsnjdnjsd> ";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"<([a-zA-z]+)( .*)>" options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
[matches enumerateObjectsUsingBlock:^(NSTextCheckingResult *result, NSUInteger idx, BOOL *stop) {
NSString* nodeName = [string substringWithRange:[result rangeAtIndex:1]];
NSString* value = [string substringWithRange:[result rangeAtIndex:2]];
NSLog(#"Regex approach: %# %#",nodeName, value);
NSLog(#"Regex approach: %#", [string stringByReplacingOccurrencesOfString:value withString:#""]);
}];
NSScanner *scanner = [NSScanner scannerWithString:string];
BOOL recordingValue = NO;
NSMutableString *valueString = [#"" mutableCopy];
[scanner setScanLocation:0];
while (![scanner isAtEnd]) {
NSString *charAtlocation = [string substringWithRange:NSMakeRange([scanner scanLocation], 1)];
if ([charAtlocation isEqualToString:#" "]){
recordingValue = YES;
[valueString appendString:#" "];
} else{
if ([charAtlocation isEqualToString:#">"]){
recordingValue = NO;
} else if (recordingValue) {
[valueString appendString:charAtlocation];
}
}
[scanner setScanLocation:[scanner scanLocation]+1];
} ;
NSLog(#"Scanner approach: %#", valueString);
NSLog(#"Scanner approach: %#", [string stringByReplacingOccurrencesOfString:valueString withString:#""]);
}
return 0;
}
Output:
Regex approach: aNodee thsisjijdsnjdnjsd
Regex approach: <aNodee>
Scanner approach: thsisjijdsnjdnjsd
Scanner approach: <aNodee>

Extract Contents of Anchor Tag

What I'm trying to do is extract the contents of a an anchor tag being stored in an NSString.
If for example I have a string with the following:
Amazon <b>Kindle</b>: Welcome
How would I go about extracting the contents of the anchor tag so that I would have the following:
https://kindle.amazon.com/&sa=U&ei=GdiWT5uCEI6BhQfihoTzDQ&ved=0CCUQFjAB&usg=AFQjCNEoRolsgoynLNS0H60VWz-9EaQdtw
Any help would be greatly appreciated!
I'm completely stumped, whereas this should be quite simple? The answer posted below keeps returning null.
If you can require Lion, then you can use NSRegularExpression.
NSString* stringToSearch = #"Amazon <b>Kindle</b>: Welcome";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"href\\s*=\\s*\"\\/url\\?q=([^\"]*)\""
options:NSRegularExpressionCaseInsensitive
error:&error];
NSTextCheckingResult* match = [regex firstMatchInString:stringToSearch options:0 range:NSMakeRange(0, [stringToSearch length])];
if(match.numberOfRanges == 2)
{
NSRange capture = [match rangeAtIndex:1];
NSString* URLString = [stringToSearch substringWithRange:capture];
NSLog(#"%#",URLString);
}
One Possible solution is by using NSScanner -
NSString *urlString = nil;
NSString *htmlString = #"Amazon <b>Kindle</b>: Welcome";
NSScanner *scanner = [NSScanner scannerWithString:htmlString];
[scanner scanUpToString:#"<a" intoString:nil];
if (![scanner isAtEnd]) {
[scanner scanUpToString:#"http" intoString:nil];
NSCharacterSet *charset = [NSCharacterSet characterSetWithCharactersInString:#">"];
[scanner scanUpToCharactersFromSet:charset intoString:&urlString];
}
NSLog(#"%#", urlString);
In Logs -
https://kindle.amazon.com/&sa=U&ei=GdiWT5uCEI6BhQfihoTzDQ&ved=0CCUQFjAB&usg=AFQjCNEoRolsgoynLNS0H60VWz-9EaQdtw