how to find number of images from file name? - objective-c

i need to know how meny image's i have from the file name exp:
i have images call:
first file:
Splash_10001.jpg
last file:
Splash_10098.jpg
and i want to inset then to array..
for(int i = 1; i <= IMAGE_COUNT; i++)
{
UIImage* image = [UIImage imageNamed:[NSString stringWithFormat:#"%#%04d.%#",self.firstImageName,i,self.imageType]];
NSLog(#"%d",i);
[imgArray addObject:image];
}
i want to replace IMAGE_COUNT with number 98 but i need to get the numbre from the string the user send me : Splash_10098.jpg
i need to Separate the Splash_10098.jpg into: nsstring:Splash_1 int:0098 nsstring:jpg
10x all!

It depends what input are of the string is granted. In the following I would search for the dot and go backwards to the maximum of digits.
By the way I could only recommend to use the multi lingual NumberFormatter instead of relying on the default conversion.
NSString * input = #"Splash_19001.jpg";
NSRange r = [input rangeOfString:#"."];
if(r.location>4){
NSString * numberPart = [input substringWithRange: NSMakeRange(r.location-4,4)];
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
[nf setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * number = [nf numberFromString:numberPart];
int val = [number intValue];
NSLog(#"intValue=%d",val);
}

I think this is what you're looking for
NSString *stringUserSendsYou = #"Splash_10098.jpg";
int IMAGE_COUNT = [[[stringUserSendsYou stringByReplacingOccurrencesOfString:#"Splash_1" withString:#""] stringByReplacingOccurrencesOfString:#".jpg" withString:#""] integerValue];

If the number length is fixed in the suffix, it would make sense to use a substring instead of trying to remove the prefix. Strip the extension and grab the last x characters, convert those into an int with either intValue or the NSNumberFormatter suggested by iOS, although that might be unnecessary if you are sure of the format of the string.
NSString *userProvidedString = #"Splash_10001.jpg";
NSString *numberString = [userProvidedString stringByDeletingPathExtension];
NSUInteger length = [numberString length];
NSInteger numberLength = 4;
if (length < numberLength)
{
NSLog(#"Error in the string");
return;
}
numberString = [numberString substringWithRange: NSMakeRange(length - 4, 4)];
NSInteger integer = [numberString integerValue];
// Do whatever you want with the integer.

Using Regex(NSRegularExpression in iOS), this can be done very easily,
Check this out,
NSError *error = NULL;
NSString *originalString = #"Splash_10098.jpg";
NSString *regexString = #"([^\?]*_[0-9])([0-9]*)(.)([a-z]*)";
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:originalString options:NSRegularExpressionCaseInsensitive range:NSMakeRange(0, [originalString length])];
NSLog(#"FileName: %#", [originalString substringWithRange:[match rangeAtIndex:1]]);
NSLog(#"Total Count: %#", [originalString substringWithRange:[match rangeAtIndex:2]]);
NSLog(#"File type: %#", [originalString substringWithRange:[match rangeAtIndex:4]]);
Result:
FileName: Splash_1
Total Count: 0098
File type: jpg

Related

Replace specific words in NSString

what is the best way to get and replace specific words in string ?
for example I have
NSString * currentString = #"one {two}, thing {thing} good";
now I need find each {currentWord}
and apply function for it
[self replaceWord:currentWord]
then replace currentWord with result from function
-(NSString*)replaceWord:(NSString*)currentWord;
The following example shows how you can use NSRegularExpression and enumerateMatchesInString to accomplish the task. I have just used uppercaseString as function that replaces a word, but you can use your replaceWord method as well:
EDIT: The first version of my answer did not work correctly if the replaced words are
shorter or longer as the original words (thanks to Fabian Kreiser for noting that!) .
Now it should work correctly in all cases.
NSString *currentString = #"one {two}, thing {thing} good";
// Regular expression to find "word characters" enclosed by {...}:
NSRegularExpression *regex;
regex = [NSRegularExpression regularExpressionWithPattern:#"\\{(\\w+)\\}"
options:0
error:NULL];
NSMutableString *modifiedString = [currentString mutableCopy];
__block int offset = 0;
[regex enumerateMatchesInString:currentString
options:0
range:NSMakeRange(0, [currentString length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
// range = location of the regex capture group "(\\w+)" in currentString:
NSRange range = [result rangeAtIndex:1];
// Adjust location for modifiedString:
range.location += offset;
// Get old word:
NSString *oldWord = [modifiedString substringWithRange:range];
// Compute new word:
// In your case, that would be
// NSString *newWord = [self replaceWord:oldWord];
NSString *newWord = [NSString stringWithFormat:#"--- %# ---", [oldWord uppercaseString] ];
// Replace new word in modifiedString:
[modifiedString replaceCharactersInRange:range withString:newWord];
// Update offset:
offset += [newWord length] - [oldWord length];
}
];
NSLog(#"%#", modifiedString);
Output:
one {--- TWO ---}, thing {--- THING ---} good

Find certain character and substring in Objective-C

I have a string..
NSString* string = #"%B999999^PDVS123456789012^PADILLA L. ^0X0000399 ?*;999999554749123456789012=00X990300000?*
What I want is to get the name PADILLA L. and 999999554749123456789012=00X990300000?*
Use NSString componentsSeparatedByString: to split the string up. First use #"^". The name will be at index 2. Then split the substring at index 3 using #";". The string at index 1 will give you the 2nd piece you want.
NSArray *substrings = [string componentsSeparatedByString:#"^"];
NSString *name = substrings[2];
name = [name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *lastpart = substrings[3];
NSArray *moresubstrings = [lastpart componentsSeparatedByString:#";"];
NSString *secondPiece = moresubstrings[1];
Without more specifics here is a brute force way:
NSString* string = #"%B999999^PDVS123456789012^PADILLA L. ^0X0000399 ?*;999999554749123456789012=00X990300000?*";
NSRange nameRange = {26, 10};
NSString *name = [string substringWithRange:nameRange];
NSRange numRange = {80, 39};
NSString *num = [string substringWithRange:numRange];
The documentation is your friend: NSString Class Reference
Without knowing what the exact input pattern is (we have your n-of-1 example only), it's going to hard to say exactly how you might parse this properly; but NSRegularExpression offers what you need (in addition to other suggested approaches):
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
#autoreleasepool {
NSString *sampleText = #"%B999999^PDVS123456789012^PADILLA L. ^0X0000399 ?*;999999554749123456789012=00X990300000?*";
NSError *regexError = nil;
NSRegularExpressionOptions options = 0;
NSString *pattern = #"^%\\w+\\^\\w+\\^([A-Za-z\\s]+\\.).+\\?\\*\\;(.+)\\?\\*$";
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:pattern options:options error:&regexError];
NSTextCheckingResult *match = [expression firstMatchInString:sampleText options:0 range:range];
if( match ) {
NSRange nameRange = [match rangeAtIndex:1];
NSRange numberRange = [match rangeAtIndex:2];
printf("name = %s ",[[sampleText substringWithRange:nameRange] UTF8String]);
printf("number = %s\n",[[sampleText substringWithRange:numberRange] UTF8String]);
}
}
}
This little Foundation application prints the following to the console:
name = PADILLA L. number = 999999554749123456789012=00X990300000
The regex used to analyze the input string may need to be tweaked depending on how the input string varies. Right now it is (unescaped):
^%\w+\^\w+\^([A-Za-z\s]+\.).+\?\*\;(.+)\?\*$

Counting occurrences of capital letters and numbers in an NSString

In PHP I am using the following code...
$passwordCapitalLettersLength = strlen(preg_replace("![^A-Z]+!", "", $password));
$passwordNumbersLength = strlen(preg_replace("/[0-9]/", "", $password));
...to count how many times capital letters and numbers appear in the password.
What is the equivalent of this in Objective C?
You can use the NSCharacterSet:
NSString *password = #"aas2dASDasd1asdASDasdas32D";
int occurrenceCapital = 0;
int occurenceNumbers = 0;
for (int i = 0; i < [password length]; i++) {
if([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[password characterAtIndex:i]])
occurenceCapital++;
if([[NSCharacterSet decimalDigitCharacterSet] characterIsMember:[password characterAtIndex:i]])
occurenceNumbers++;
}
This can be done fairly concisely using the abilities of NSString and NSCharacterSet, instead of the need to iterate manually.
A decrement of 1 is required as componentsSeparatedByCharactersInSet: will always return at least one element, and that one element won't count your separations.
NSString* password = #"dhdjGHSJD7d56dhHDHa7d5bw3/%£hDJ7hdjs464525";
NSArray* capitalArr = [password componentsSeparatedByCharactersInSet:[NSCharacterSet uppercaseLetterCharacterSet]];
NSLog(#"Number of capital letters: %ld", (unsigned long) capitalArr.count - 1);
NSArray* numericArr = [password componentsSeparatedByCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
NSLog(#"Number of numeric digits: %ld", (unsigned long) numericArr.count - 1);
Original answer: Whilst the code you've provided won't cover all bases, if you need to keep using those regular expressions for safety/risk reasons, you can do so below.
You can use RegEx in Objective-C. Saves manually iterating through the String, and keeps the code concise. It also means because you aren't iterating manually, you could potentially get a performance boost, as you can let the compiler/framework writer optimize it.
// Testing string
NSString* password = #"dhdjGHSJD7d56dhHDHa7d5bw3/%£hDJ7hdjs464525";
NSRegularExpression* capitalRegex = [NSRegularExpression regularExpressionWithPattern:#"[A-Z]"
options:0
error:nil];
NSRegularExpression* numbersRegex = [NSRegularExpression regularExpressionWithPattern:#"[0-9]"
options:0
error:nil];
NSLog(#"Number of capital letters: %ld", (unsigned long)[capitalRegex matchesInString:password
options:0
range:NSMakeRange(0, password.length)].count);
NSLog(#"Number of numeric digits: %ld", (unsigned long)[numbersRegex matchesInString:password
options:0
range:NSMakeRange(0, password.length)].count);

Replace characters in NSString

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

How to get substring of NSString?

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