I have search for this but could not found in Apple documentation
You probably want - (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)aRange. The range argument is an NSRange indicating where in the haystack to look for the needle. Passing NSMakeRange(startIndex, [haystack length]-startIndex) should do what you want.
NSRange range = [string rangeOfString:searchString
options:0
range:NSMakeRange(startIndex, [string length]-startIndex)];
if (range.length != 0) {
NSString* resultString = [string substringWithRange:range];
}
You mean you couldn't find this documentation page by searching NSString and clicking the first link?
NSString *substring = [string substringFromIndex:startIndex];
Related
As the title suggests, I would like to get the last word out of an NSString.
I thought using this code:
NSArray *listItems = [someNSStringHere componentsSeparatedByString:#" "];
NSString *lastWordString = [NSString stringWithFormat:#"%#", listItems.lastObject];
anotherNSStringHere = lastWordString;
But I think the NSArray will take a time to load if it's big (and it is big), and it wouldn't recognize a word separated by a comma.
Thanks for helping!
If you want to be super-robust:
__block NSString *lastWord = nil;
[someNSStringHere enumerateSubstringsInRange:NSMakeRange(0, [someNSStringHere length]) options:NSStringEnumerationByWords | NSStringEnumerationReverse usingBlock:^(NSString *substring, NSRange subrange, NSRange enclosingRange, BOOL *stop) {
lastWord = substring;
*stop = YES;
}];
(This should also work with non-Roman languages; iOS 4+/OS X 10.6+.)
Basic explanation:
-enumerateSubstringsInRage:options:usingBlock: does what it says on the tin: it enumerates substrings, which are defined by what you pass in as the options. NSStringEnumerationByWords says "I want words given to me", and NSStringEnumerationReverse says "start at the end of the string instead of the beginning".
Since we're starting from the end, the first word given to us in substring will be the last word in the string, so we set lastWord to that, and then set the BOOL pointed to by stop to YES, so the enumeration stops right away.
lastWord is of course defined as __block so we can set it inside the block and see it outside, and it's initialized to nil so if the string has no words (e.g., if it's empty or is all punctuation) we don't crash when we try to use lastWord.
Give this a try:
NSRange range = [someNSStringHere rangeOfString:#" " options:NSBackwardsSearch];
NSString *result = [someNSStringHere substringFromIndex:range.location+1];
If you wanted to use a regular expression (which can be useful if you want to start getting more complicated in terms of what you're looking for at the end of your string), you could do something like:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\S+\\Z" options:0 error:nil];
NSTextCheckingResult *found = [regex firstMatchInString:inputString options:0 range:NSMakeRange(0, [inputString length])];
if (found.range.location != NSNotFound)
result = [inputString substringWithRange:found.range];
That works great as it also recognizes symbols like # and # which enumerateSubstringsInRange: doesn't do.
NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray *components = [someString componentsSeparatedByCharactersInSet:charSet];
NSString *lastWord = components.lastObject;
The most efficient way is likely to start at the end of the string, examine each character to see if it's part of what you define as a word, and then extract the word you want using substringFromIndex: or substringWithRange:.
You can read symbols from the end of the your string and copy them at the 0 index to result string. Whether you read space or comma, result string wil contain the last word
You could use NSString's function rangeOfSubstring:options: to determine it. For example:
Search the string for a space, using a backwards search option to start the search from the end of the string.
NSRange r = [string rangeOfString:#" " options:NSBackwardsSearch];
This will find the location of the last word of the string. Now just get the string using substringWithRange: For Example:
NSRange found = NSMakeRange(NSMaxRange(r), string.length - NSMaxRange(r));
NSString *foundString = [string substringWithRange:found];
Where r is the range from earlier.
Also be careful to make sure that you check r actually exists. If there is only 1 word in the string, then r will be {NSNotFound, 0}
Hope I could help!
Ben
I am trying to replace all characters except last 4 in a String with *'s.
In objective-c there is a method in NSString class replaceStringWithCharactersInRange: withString: where I would give it range (0,[string length]-4) ) with string #"*". This is what it does: 123456789ABCD is modified to *ABCD while I am looking to make ********ABCD.
I understand that it replaced range I specified with string object. How to accomplish this ?
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\d" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *newString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#"*"];
This looks like a simple problem... get the first part string and return it with the last four characters appended to it.
Here is a function that returns the needed string :
-(NSString *)neededStringWithString:(NSString *)aString {
// if the string has less than or 4 characters, return nil
if([aString length] <= 4) {
return nil;
}
NSUInteger countOfCharToReplace = [aString length] - 4;
NSString *firstPart = #"*";
while(--countOfCharToReplace) {
firstPart = [firstPart stringByAppendingString:#"*"];
}
// range for the last four
NSRange lastFourRange = NSMakeRange([aString length] - 4, 4);
// return the combined string
return [firstPart stringByAppendingString:
[aString substringWithRange:lastFourRange]];
}
The most unintuitive part in Cocoa is creating the repeating stars without some kind of awkward looping. stringByPaddingToLength:withString:startingAtIndex: allows you to create a repeating string of any length you like, so once you have that, here's a simple solution:
NSInteger starUpTo = [string length] - 4;
if (starUpTo > 0) {
NSString *stars = [#"" stringByPaddingToLength:starUpTo withString:#"*" startingAtIndex:0];
return [string stringByReplacingCharactersInRange:NSMakeRange(0, starUpTo) withString:stars];
} else {
return string;
}
I'm not sure why the accepted answer was accepted, since it only works if everything but last 4 is a digit. Here's a simple way:
NSMutableString * str1 = [[NSMutableString alloc]initWithString:#"1234567890ABCD"];
NSRange r = NSMakeRange(0, [str1 length] - 4);
[str1 replaceCharactersInRange:r withString:[[NSString string] stringByPaddingToLength:r.length withString:#"*" startingAtIndex:0]];
NSLog(#"%#",str1);
You could use [theString substringToIndex:[theString length]-4] to get the first part of the string and then combine [theString length]-4 *'s with the second part. Perhaps their is an easier way to do this..
NSMutableString * str1 = [[NSMutableString alloc]initWithString:#"1234567890ABCD"];
[str1 replaceCharactersInRange:NSMakeRange(0, [str1 length] - 4) withString:#"*"];
NSLog(#"%#",str1);
it works
The regexp didn't work on iOS7, but perhaps this helps:
- (NSString *)encryptString:(NSString *)pass {
NSMutableString *secret = [NSMutableString new];
for (int i=0; i<[pass length]; i++) {
[secret appendString:#"*"];
}
return secret;
}
In your case you should stop replacing the last 4 characters. Bit crude, but gets the job done
I would like to count my NSArray object of my NSString. My NSArray has #"a", #"w" objects, and my string is #"abcdefgw". I would like to know how many times the #"w" object is there in my string.
You can use - (NSArray *)componentsSeparatedByString:(NSString *)separator, though this may have boundary issues. You can also use stringByReplacingOccurrencesOfString:withString: like this:
NSString *shortString = [myString stringByReplacingOccurrencesOfString:#"w" withString:#""];
return mystring.length-shortString.length;
if you are looking to count substrings you will have to search for substrings then shrink the range each time... something like.
-(NSInteger)occurrencesOfSubstring:(NSString *)substring inString:(NSString *)string
{
int occurrences =0;
NSRange searchRange = NSMakeRange(0, [string length]);
NSRange foundRange;
do {
foundRange = [string rangeOfString:substring options:NSCaseInsensitiveSearch range:searchRange];
if ((foundRange.location != NSNotFound)) {
occurrences++;
searchRange.location = foundRange.location+foundRange.length;
searchRange.length = [string length] - (foundRange.location+foundRange.length);
}
}while (foundRange.location != NSNotFound);
return occurrences;
}
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".
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.
Here's a slightly less complicated answer:
NSString *myString = #"abcdefg";
NSString *mySmallerString = [myString substringToIndex:4];
See also substringWithRange and substringFromIndex
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:#":"];
Use this also
NSString *ChkStr = [MyString substringWithRange:NSMakeRange(5, 26)];
Note - Your NSMakeRange(start, end) should be NSMakeRange(start, end- start);
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);
is it possible to use the method rangeOfString to search for a NSString starting from a given offset?
Something more similar to the strpos function in PHP.
Thanks
Not -rangeOfString:, but a similar method - -rangeOfString:options:range:.
(Edit: An example)
NSString *string = #"YaddaYaddaYadda";
NSString *searchString = #"Yadda";
NSRange thisCharRange, searchCharRange;
searchCharRange = NSMakeRange(3, [string length]);
thisCharRange = [string rangeOfString:searchString options:0 range:searchCharRange];
NSLog(#"thisCharRange: %#", NSStringFromRange(thisCharRange));
I find a problem with the example up there. It'll cause "Range or index out of bounds".
searchCharRange = NSMakeRange(3, [string length]);
should change to
searchCharRange = NSMakeRange(3, [string length] - 3);
that is,the range's length should not be longer than the original string's length - the range's start location.