81

If I want to get a value from the NSString @"value:hello World:value", what should I use?

The return value I want is @"hello World".

thegrinner
  • 11,546
  • 5
  • 41
  • 64
Csabi
  • 3,097
  • 17
  • 59
  • 107
  • possible duplicate [search within NSstring](http://stackoverflow.com/questions/3771211/search-within-nsstring) or [Search through NSString using Regular Expression.](http://stackoverflow.com/questions/4353834/search-through-nsstring-using-regular-expression) – Black Frog Apr 15 '11 at 11:48
  • I'm voting to close this question as unclear what your asking. There's no indication at all of exactly what is wanted here. Do you want to just return `"hello World"`? `return @"hello World"`. Do you want to return just what's between colons? Do you want to strip everything left of the left-most colon and everything right of the right-most colon? There is no clearly defined input-output criteria for this question (as we see with the resulting list of questions that all solve the problem with a wild array of approaches). – nhgrif Aug 25 '15 at 12:55

5 Answers5

162

Option 1:

NSString *haystack = @"value:hello World:value";
NSString *haystackPrefix = @"value:";
NSString *haystackSuffix = @":value";
NSRange needleRange = NSMakeRange(haystackPrefix.length,
                                  haystack.length - haystackPrefix.length - haystackSuffix.length);
NSString *needle = [haystack substringWithRange:needleRange];
NSLog(@"needle: %@", needle); // -> "hello World"

Option 2:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^value:(.+?):value$" options:0 error:nil];
NSTextCheckingResult *match = [regex firstMatchInString:haystack options:NSAnchoredSearch range:NSMakeRange(0, haystack.length)];
NSRange needleRange = [match rangeAtIndex: 1];
NSString *needle = [haystack substringWithRange:needleRange];

This one might be a bit over the top for your rather trivial case though.

Option 3:

NSString *needle = [haystack componentsSeparatedByString:@":"][1];

This one creates three temporary strings and an array while splitting.


All snippets assume that what's searched for is actually contained in the string.

Ky -
  • 30,724
  • 51
  • 192
  • 308
Regexident
  • 29,441
  • 10
  • 93
  • 100
76

Here's a slightly less complicated answer:

NSString *myString = @"abcdefg";
NSString *mySmallerString = [myString substringToIndex:4];

See also substringWithRange and substringFromIndex

Shaun Neal
  • 1,183
  • 1
  • 10
  • 12
18

Here's a simple function that lets you do what you are looking for:

- (NSString *)getSubstring:(NSString *)value betweenString:(NSString *)separator
{
    NSRange firstInstance = [value rangeOfString:separator];
    NSRange secondInstance = [[value substringFromIndex:firstInstance.location + firstInstance.length] rangeOfString:separator];
    NSRange finalRange = NSMakeRange(firstInstance.location + separator.length, secondInstance.location);

    return [value substringWithRange:finalRange];
}

Usage:

NSString *myName = [self getSubstring:@"This is my :name:, woo!!" betweenString:@":"];
Garett
  • 552
  • 6
  • 15
  • 1
    In case it's illuminating, I can tell you my reason for voting up the other answer. I would rather write two lines of code than six. – Le Mot Juiced Nov 15 '13 at 17:01
  • 2
    The problem is that those two lines of code only solve a specific case that will never exist for anyone -- probably not even for the person that asked it. – Garett Nov 19 '13 at 22:39
  • `getSubstring:…` should be called `substringInString:…` as you're not passing a substring to it and methods starting with `get…` are usually expected to be passed a buffer pointer to write to. `substringFromIndex:` creates an intermediate substring, which is unnecessary, that's what `rangeOfString:options:range:` is for. Last by wrapping the unsafe snippet in a supposedly generic method you're masking a bug: If the separator exists a single or less times in the string you'll get an out of range exception. – Regexident May 07 '14 at 15:57
14

Use this also

NSString *ChkStr = [MyString substringWithRange:NSMakeRange(5, 26)];

Note - Your NSMakeRange(start, end) should be NSMakeRange(start, end- start);

Abhishek Mishra
  • 1,625
  • 16
  • 32
13

Here is a little combination of @Regexident Option 1 and @Garett answers, to get a powerful string cutter between a prefix and suffix, with MORE...ANDMORE words on it.

NSString *haystack = @"MOREvalue:hello World:valueANDMORE";
NSString *prefix = @"value:";
NSString *suffix = @":value";
NSRange prefixRange = [haystack rangeOfString:prefix];
NSRange suffixRange = [[haystack substringFromIndex:prefixRange.location+prefixRange.length] rangeOfString:suffix];
NSRange needleRange = NSMakeRange(prefixRange.location+prefix.length, suffixRange.location);
NSString *needle = [haystack substringWithRange:needleRange];
NSLog(@"needle: %@", needle);
Jeffrey Neo
  • 3,693
  • 2
  • 26
  • 30
  • Now this works! I tried Regixident's option 1, it didn't work for me. I can't think why. I've been searching for a solution to get a string inside a `````` tags in my project to make those strings italic. :) – Glenn Posadas Jul 09 '18 at 18:35