I want to replace several different groups of characters in one NSString. Currently I am doing it with several repeating methods, however I am hoping there is a way of doing this in one method:
NSString *result = [html stringByReplacingOccurrencesOfString:#"<B&" withString:#" "];
NSString *result2 = [result stringByReplacingOccurrencesOfString:#"</B>" withString:#" "];
NSString *result3 = [result2 stringByReplacingOccurrencesOfString:#"gt;" withString:#" "];
return [result3 stringByReplacingOccurrencesOfString:#" Description " withString:#""];
I don't think there is anything in the SDK, but you could at least use a category for this so you can write something like this:
NSDictionary *replacements = [NSDictionary dictionaryWithObjectsAndKeys:
#" ", #"<B&",
#" ", #"</B>",
#" ", #"gt;"
#"" , #" Description ",
nil];
return [html stringByReplacingStringsFromDictionary:replacements];
... by using something like the following:
#interface NSString (ReplaceExtensions)
- (NSString *)stringByReplacingStringsFromDictionary:(NSDictionary *)dict;
#end
#implementation NSString (ReplaceExtensions)
- (NSString *)stringByReplacingStringsFromDictionary:(NSDictionary *)dict
{
NSMutableString *string = [self mutableCopy];
for (NSString *target in dict) {
[string replaceOccurrencesOfString:target withString:[dict objectForKey:target]
options:0 range:NSMakeRange(0, [string length])];
}
return [string autorelease];
}
#end
In modern Objective C with ARC:
-(NSString*)stringByReplacingStringsFromDictionary:(NSDictionary*)dict
{
NSMutableString *string = self.mutableCopy;
for(NSString *key in dict)
[string replaceOccurrencesOfString:key withString:dict[key] options:0 range:NSMakeRange(0, string.length)];
return string.copy;
}
Related
I have a NSString, for example:
"Had a #great time at the #party last night."
I want to separate this into an array, as so:
"Had a "
"#great"
" time at the "
"#party"
" last night."
How could i do this?
NSString *str = #"Had a #great time at the #party last night.";
NSMutableArray *arr = [[NSMutableArray alloc] init];
NSArray *array = [str componentsSeparatedByString:#"#"];
NSMutableString *retStr= [[NSMutableString alloc] initWithString:[array objectAtIndex:0]];
[arr addObject:retStr];
for(int i=1 ; i<[array count];i++)
{
NSArray *array1 = [[array objectAtIndex:i] componentsSeparatedByString:#" "];
{
NSMutableString *retStr= [[NSMutableString alloc]init];
for (int i = 0;i< [array1 count]; i++)
{
if(i==0)
{
[retStr appendFormat:#" #%# ",[array1 objectAtIndex:i]];
[arr addObject:retStr];
retStr= [[NSMutableString alloc]init];
}
else
{
[retStr appendFormat:#"%# ",[array1 objectAtIndex:i]];
}
}
[arr addObject:retStr];
}
}
NSLog(#"%#",arr);
You will get the corect output as you want
try like this it'l helps you,
NSString *str=#"how are #you #friend";
NSArray *arr=[str componentsSeparatedByString:#" "];
NSPredicate *p = [NSPredicate predicateWithFormat:#"not SELF contains '#'"];
NSArray *b = [arr filteredArrayUsingPredicate:p];
NSLog(#"%#",b);
above predicate will returns the words which are not containg '#' symbol
NSPredicate *p = [NSPredicate predicateWithFormat:#"not SELF like '#*'"];
it'l returns the words which are not started with the letter '#'
O/P:-
(
how,
are
)
EDIT:-
NSString *str=#"how are #you #friend";
NSArray *arr=[str componentsSeparatedByString:#"#"];
NSMutableArray *result=[[NSMutableArray alloc]initWithObjects:[arr objectAtIndex:0], nil];
for(int i=1;i<[arr count];i++){
[result addObject:[NSString stringWithFormat:#"#%#",[arr objectAtIndex:i]]];
}
NSLog(#"%#",result);
O/P:-
(
"how are ",
"#you ",
"#friend"
)
Try to use this regexp: (#.+?\\b)|(.+?(?=#|$))
It find words which begins with hashtag and subsequences which ends with hashtag
NSString * string = #"Had a #great time at the #party last night.";
NSError * error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:#"((#.+?\\b)|(.+?(?=#|$)))"
options:0
error:&error];
NSArray * matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult* match in matches ) {
NSLog(#"%#", [string substringWithRange:[match range]]);
}
Output:
2013-04-29 16:57:51.688 Had a
2013-04-29 16:57:51.689 #great
2013-04-29 16:57:51.690 time at the
2013-04-29 16:57:51.691 #party
2013-04-29 16:57:51.692 last night.
If you want to do it efficiently in a single pass on the string you can try something like (scratch code - test for bugs/boundary cases etc...):
int main (int argc, const char * argv[])
{
NSString *msg = #"Had a #great time at the #party last night.";
Boolean inTag = NO;
NSMutableArray *segments = [[NSMutableArray alloc] init];
NSUInteger idx = 0;
NSUInteger i=0;
for (; i < [msg length]; i++)
{
unichar ch = [msg characterAtIndex:i];
if (inTag && ch == ' ')
{
[segments addObject:[msg substringWithRange:NSMakeRange(idx, i - idx)]];
idx = i;
inTag = NO;
}
if (ch == '#')
{
[segments addObject:[msg substringWithRange:NSMakeRange(idx, i - idx)]];
idx = i;
inTag = YES;
}
}
if (i > idx)
{
[segments addObject:[msg substringWithRange:NSMakeRange(idx, i - idx - 1)]];
}
for(NSString *seg in segments)
{
NSLog(#"%#", seg);
}
}
This outputs:
2013-04-29 08:34:34.984 Craplet[95591:707] Had a
2013-04-29 08:34:34.986 Craplet[95591:707] #great
2013-04-29 08:34:34.986 Craplet[95591:707] time at the
2013-04-29 08:34:34.987 Craplet[95591:707] #party
2013-04-29 08:34:34.987 Craplet[95591:707] last night
Try this:
for (int i=0;i<[YourArray count];i++) {
NSString * mystr=[YourArray objectAtIndex:i];
NSString *temp=[mystr substringToIndex:1];
if (![temp isEqualToString:#"#"]) {
//add your string in new array and use this arry.....
}
}
try this code
for (int i=0;i<[YourArray count];i++) {
NSString * str=[YourArray objectAtIndex:i];
NSString *myString=[str substringToIndex:1];
NSString *stringfinal = [myString
stringByReplacingOccurrencesOfString:#"#" withString:#""];
}
Try using regular expressions. With this code you'll be able to extract the hashtags:
NSString * string = #"Had a #great time at the #party last night.";
NSError * error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:#"((?:#){1}[\\w\\d]{1,140})" options:0 error:&error];
NSArray * matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for ( NSTextCheckingResult* match in matches )
{
NSString * hashtag = [string substringWithRange:[match range]];
NSLog(#"match: %#", hashtag);
}
With this, you'll be able to build up the array result you're looking for.
Try
NSString *string = #"Had a #great time at the #party last night.";
NSArray *components = [string componentsSeparatedByString:#" "];
NSMutableArray *formattedArray = [NSMutableArray array];
NSMutableString *mutableString = [NSMutableString string];
for (NSString *string in components)
{
if (![string hasPrefix:#"#"]){
if (!mutableString){
mutableString = [NSMutableString string];
}
[mutableString appendFormat:#" %#",string];
}else{
if (mutableString) {
[formattedArray addObject:mutableString];
mutableString = nil;
}
[formattedArray addObject:string];
}
}
if (mutableString) {
[formattedArray addObject:mutableString];
}
NSLog(#"%#",formattedArray);
EDIT :
(
" Had a",
"#great",
" time at the",
"#party",
" last night."
)
One-pass solution with NSScanner
NSString *string = #"Had a #great time at the #party last night.";
NSMutableArray *array = [#[] mutableCopy];
NSScanner *scanner = [NSScanner scannerWithString:string];
while (![scanner isAtEnd]) {
NSString *s;
[scanner scanUpToString:#"#" intoString:&s];
if(s) [array addObject:s];
s = nil;
[scanner scanUpToString:#" " intoString:&s];
if(s) [array addObject:s];
}
result:
(
"Had a ",
"#great",
"time at the ",
"#party",
"last night."
)
if you want to preserve the leading whitespace, alter it slightly to
NSString *string = #"Had a #great time at the #party last night.";
NSMutableArray *array = [#[] mutableCopy];
NSScanner *scanner = [NSScanner scannerWithString:string];
BOOL firstSegment = YES;
while (![scanner isAtEnd]) {
NSString *s;
[scanner scanUpToString:#"#" intoString:&s];
if(s) [array addObject: (!firstSegment) ? [#" " stringByAppendingString:s] : s];
s = nil;
[scanner scanUpToString:#" " intoString:&s];
if(s) [array addObject:s];
firstSegment = NO;
}
result:
(
"Had a ",
"#great",
" time at the ",
"#party",
" last night."
)
I need to extract a variable's value from a string, which happens to be a URL. The string/url is loaded as part of a separate php query, not the url in the browser.
The url's will look like:
http://gmail.com?access_token=ab8w4azq2xv3dr4ab37vvzmh&token_type=bearer&expires_in=3600
How can I capture the value of the access_token which in this example is ab8w4azq2xv3dr4ab37vvzmh?
This code should do it:
- (NSString *)extractToken:(NSURL *)URL
{
NSString *urlString = [URL absoluteString];
NSRange start = [urlString rangeOfString:#"access_token="];
if (start.location != NSNotFound)
{
NSString *token = [urlString substringFromIndex:start.location+start.length];
NSRange end = [token rangeOfString:#"&"];
if (end.location != NSNotFound)
{
//trim off other parameters
token = [token substringToIndex:end.location];
}
return token;
}
//not found
return nil;
}
Alternatively, here is a more general solution that will extract all the query parameters into a dictionary:
- (NSDictionary *)URLQueryParameters:(NSURL *)URL
{
NSString *queryString = [URL query];
NSMutableDictionary *result = [NSMutableDictionary dictionary];
NSArray *parameters = [queryString componentsSeparatedByString:#"&"];
for (NSString *parameter in parameters)
{
NSArray *parts = [parameter componentsSeparatedByString:#"="];
NSString *key = [[parts objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([parts count] > 1)
{
id value = [[parts objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[result setObject:value forKey:key];
}
}
return result;
}
Good Category for NSDictionary:
#import "NSDictionary+URL.h"
#implementation NSDictionary (URL)
+ (NSDictionary *)dictionaryWithUrlString:(NSString *)urlString{
NSRange urlRange = [urlString rangeOfString:#"?"];
if(urlRange.length>0){
urlString = [urlString substringFromIndex:urlRange.length+urlRange.location];
}
NSArray *pairsArray = [urlString componentsSeparatedByString:#"&"];
NSMutableDictionary *parametersDictionary = [[NSMutableDictionary alloc] initWithCapacity:[pairsArray count]];
for(NSString *pairString in pairsArray){
NSArray *valuesArray = [pairString componentsSeparatedByString:#"="];
if([valuesArray count]==2){
[parametersDictionary setValue:[valuesArray objectAtIndex:1] forKey:[valuesArray objectAtIndex:0]];
}
}
return [parametersDictionary autorelease];
}
#end
NSMutableDictionary *querycomponent = [[NSMutableDictionary alloc] init];
if (![query isEqualToString:#""]){
NSArray *queryArray = [query componentsSeparatedByString:#"&"];
for (NSString *subquery in queryArray){
NSArray *subqueryArray = [subquery componentsSeparatedByString:#"="];
NSString *key = [subqueryArray objectAtIndex:0];
NSString *val = [subqueryArray objectAtIndex:1];
[querycomponent setObject:val forKey:key];
}
NSLog(#"querycomponent %#",querycomponent);
}
I want to open an other application using
[[UIApplication sharedApplication]openURL:[[NSURL alloc]initWithString:myString]];
as log as myString is like
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",#"123"];
it works fine but if I try to use an NSDictionary like
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",userInfo];
it fails without an error
Hope you can help me.
Try enumerating all the elements in your dictionary and appending those to your URL.
NSMutableString *params = [[[NSMutableString alloc] init] autorelease];
NSEnumerator *keys = [userInfo keyEnumerator];
NSString *name = [keys nextObject];
while (nil != name) {
[params appendString: name];
[params appendString: #"="];
[params appendString: [userInfo objectForKey:name]];
name = [keys nextObject];
if (nil != name) {
[params appendString: #"&"];
}
}
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?%#",params];
When you use an NSDictionary in the format string, you get a URL that looks like this:
testHandleOpenUrl://?{
bar = foo;
}
The result of calling -description on userInfo is simply substituted for the %#. Presumably, you want to pass parameters contained in the dictionary in the URL. Probably something like this:
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:#"bar", #"foo", nil];
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://?foo=%#", [userInfo objectForKey:#"foo"]];
NSLog(#"myString: %#", myString); // prints "myString: testHandleOpenUrl://?foo=bar"
NSString * paramString = #"";
int i = 0;
for(NSString * key in [userInfo allKeys]){
NSString * value = (NSString*)[userInfo objectForKey:key];
NSString * valueParam = [NSString stringWithFormat:#"%#%#=%#",(i==0)?#"?":#"&",key,value];
paramString = [paramString stringByAppendingString:valueParam];
i++;
}
NSString *myString=[NSString stringWithFormat:#"testHandleOpenUrl://%#", paramString];
I have a string with certain pattern. I need to search for the pattern and replace the string inside that pattern. For eg :
NSString *string = #"{Hello} ({World}) ({How}) ({Are}) ({You})";
NSString *result = nil;
// Determine "{" location
NSRange startRange = [string rangeOfString:#"{" options:NSCaseInsensitiveSearch];
if (startRange.location != NSNotFound)
{
// Determine "}" location according to "{" location
NSRange endRange;
endRange.location = startRange.length + startRange.location;
endRange.length = [string length] - endRange.location;
endRange = [string rangeOfString:#"}" options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location != NSNotFound)
{
// bracets found: retrieve string between them
startRange.location += startRange.length;
startRange.length = endRange.location - startRange.location;
result = [string substringWithRange:startRange];
}
}
Here I am able to extract the first substring that is between "{ }" ie - "Hello" but I also need to continue the check and want to extract other strings.
Try this one:
NSString *string = #"{Hello} ({World}) ({How}) ({Are}) ({You})";
//NSString *result = nil;
// Determine "{" location
NSArray *array=[string componentsSeparatedByString:#"{"];
for(NSString *str in array){
NSString *newString=[[str componentsSeparatedByString:#"}"] objectAtIndex:0];
NSLog(#"%#",newString);
}
try this :
NSString *string = #"{Hello} ({World}) ({How}) ({Are}) ({You})";
NSMutableString *result = [[NSMutableString alloc] init];
NSArray *tempArray = [[string componentsSeparatedByString:#" "] mutableCopy];
for (int i=0; i < [tempArray count]; i++)
{
NSString *tempStr = [tempArray objectAtIndex:i];
NSRange startRange = [tempStr rangeOfString:#"{" options:NSCaseInsensitiveSearch];
if (startRange.location != NSNotFound)
{
// Determine "}" location according to "{" location
NSRange endRange;
endRange.location = startRange.length + startRange.location;
endRange.length = [tempStr length] - endRange.location;
endRange = [tempStr rangeOfString:#"}" options:NSCaseInsensitiveSearch range:endRange];
if (endRange.location != NSNotFound)
{
// bracets found: retrieve string between them
startRange.location += startRange.length;
startRange.length = endRange.location - startRange.location;
//result = [tempStr substringWithRange:startRange];
[result appendString:[NSString stringWithFormat:#"%# ",[tempStr substringWithRange:startRange]]];
NSLog(#"%# ",result);
}
}
}
Take care for release for tempArray and result
I happen to have this code lying around. I think it does exactly what you want. I implemented it as a category on NSString. You use it like this:
NSString *template = #"{Hello} ({World}) ({How}) etc etc";
NSDictionary *vars = [NSDictionary dictionaryWithObjectsAndKeys:
#"Bonjour", #"Hello",
#"Planet Earth", #"World",
#"Como", #"How",
// etc.
nil];
NSString *expandedString = [template stringByExpandingTemplateWithVariables:vars];
// expandedString is #"Bonjour (Planet Earth) (Como) etc etc"
Here's the code.
File NSString+TemplateExpansion.h
#import <Foundation/Foundation.h>
#interface NSString (TemplateExpansion)
- (NSString *)stringByExpandingTemplateWithVariables:(NSDictionary *)dictionary;
#end
File NSString+TemplateExpansion.m
#import "NSString+TemplateExpansion.h"
#implementation NSString (TemplateExpansion)
- (NSString *)stringByExpandingTemplateWithVariables:(NSDictionary *)dictionary
{
NSUInteger myLength = self.length;
NSMutableString *result = [NSMutableString stringWithCapacity:myLength];
NSRange remainingRange = NSMakeRange(0, myLength);
while (remainingRange.length > 0) {
NSRange leftBraceRange = [self rangeOfString:#"{" options:0 range:remainingRange];
if (leftBraceRange.location == NSNotFound)
break;
NSRange afterLeftBraceRange = NSMakeRange(NSMaxRange(leftBraceRange), myLength - NSMaxRange(leftBraceRange));
NSRange rightBraceRange = [self rangeOfString:#"}" options:0 range:afterLeftBraceRange];
if (rightBraceRange.location == NSNotFound)
break;
NSRange beforeLeftBraceRange = NSMakeRange(remainingRange.location, leftBraceRange.location - remainingRange.location);
[result appendString:[self substringWithRange:beforeLeftBraceRange]];
remainingRange = NSMakeRange(NSMaxRange(rightBraceRange), myLength - NSMaxRange(rightBraceRange));
NSRange keyRange = NSMakeRange(NSMaxRange(leftBraceRange), rightBraceRange.location - NSMaxRange(leftBraceRange));
NSString *key = [self substringWithRange:keyRange];
NSString *value = [dictionary objectForKey:key];
if (value)
[result appendString:value];
}
[result appendString:[self substringWithRange:remainingRange]];
return result;
}
#end
I have string like 123-123-1234 so I want to convert string into this format
(123) 123-1234 so any idea to develop this functionality.
Thanks in advance.
I think something like this:
NSString *list = #"123-123-1234";
NSArray *listItems = [list componentsSeparatedByString:#"-"];
NSString *result = [NSString stringWithFormat:#"(%#) %#-%#", [listItem objectAtIndex:0], [listItem objectAtIndex:1], [listItem objectAtIndex:2]];
NSString * original = #"123-123-1234";
NSArray * components = [original componentsSeparatedByString:#"-"];
NSString * first = [NSString stringWithFormat:#"(%#)",[components objectAtIndex:0] ];
NSString * second = [NSString stringWithFormat:#"%#-%#",[components objectAtIndex:1],[components objectAtIndex:2]];
NSString * finalString = [NSString stringWithFormat:#"%#%#",first,second];
NSLog(#"Final Result = %#",finalString);
NSString *str = #"123-123-1234";
NSArray *arrForDate = [str componentsSeparatedByString: #"-"];
NSString *str1 = [NSString stringWithFormat:#"(%#) %#-%#",[arrForDate objectAtIndex:0],[arrForDate
objectAtIndex:1],[arrForDate objectAtIndex:2]];
NSLog(#"str1 %#",str1);
TESTED CODE: 100% WORKS
NSString *inputString=#"123-123-1234";
NSArray *TotalString=[inputString componentsSeparatedByString:#"-"];
NSString *outputString = [NSString stringWithFormat:#"(%#) %#-%#",[TotalString objectAtIndex:0],[TotalString objectAtIndex:1],[TotalString objectAtIndex:2]];
NSLog(#"outputString is : %# \n\n",outputString);
OUTPUT:
outputString is : (123) 123-1234
For Dynamic Sollution:
NOTE: if u have more dashes with ur string then it is really hard code everything with objectAtIndex with number 0,1,2,....
moreover it will crash if it has unexpected length
so here is the solution for this
NSString *inputString=#"123-123-1234";
NSArray *TotalString=[inputString componentsSeparatedByString:#"-"];
NSMutableString *outputString=[NSMutableString string];
for (NSMutableString *obj in TotalString) {
if ([TotalString objectAtIndex:0] == obj && [outputString length]<=0) {
outputString=[[outputString stringByAppendingFormat:#"(%#)",obj] mutableCopy];
}
else if ([TotalString objectAtIndex:1] == obj) {
outputString=[[outputString stringByAppendingFormat:#"%#%#",#" ",obj] mutableCopy];
}
else {
outputString=[[outputString stringByAppendingFormat:#"-%#",obj] mutableCopy];
}
}
OUTPUT:
outputString is : (123) 123-1234
NSString *list = #"123-123-1234";
NSArray *listItems = [list componentsSeparatedByString:#"-"];
NSString *result = [NSString stringWithFormat:#"(%#) %#-%#", [listItem objectAtIndex:0], [listItem objectAtIndex:1], [listItem objectAtIndex:2]];