Andrew
Andrew

Reputation: 16051

Separate words from a NSString which are preceded by a hashtag

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?

Upvotes: 0

Views: 930

Answers (9)

vikingosegundo
vikingosegundo

Reputation: 52237

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."
)

Upvotes: 0

Anupdas
Anupdas

Reputation: 10201

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."
)

Upvotes: 0

Balu
Balu

Reputation: 8460

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"
)

Upvotes: 3

Mikhail
Mikhail

Reputation: 4311

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.

Upvotes: 1

bryanmac
bryanmac

Reputation: 39306

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

Upvotes: 1

Divyam shukla
Divyam shukla

Reputation: 2046

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

Upvotes: 4

atxe
atxe

Reputation: 5079

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.

Upvotes: 0

kirti Chavda
kirti Chavda

Reputation: 3015

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:@""];

    }

Upvotes: 0

SAMIR RATHOD
SAMIR RATHOD

Reputation: 3506

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.....
        }
    }

Upvotes: 0

Related Questions