Detecting if a character is either a letter or a number - iphone

In objective-c, how would I check if a single character was either a letter or a number? I would like to eliminate all other characters.

To eliminate non letters:
NSString *letters = #"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSCharacterSet *notLetters = [[NSCharacterSet characterSetWithCharactersInString:letters] invertedSet];
NSString *newString = [[string componentsSeparatedByCharactersInSet:notLetters] componentsJoinedByString:#""];
To check one character at a time:
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if ([notLetters characterIsMember:c]) {
...
}
}

NSCharacterSet *validChars = [NSCharacterSet alphanumericCharacterSet];
NSCharacterSet *invalidChars = [validChars invertedSet];
NSString *targetString = [[NSString alloc] initWithString: #"..."];
NSArray *components = [targetString componentsSeparatedByCharactersInSet:invalidChars];
NSString *resultString = [components componentsJoinedByString:#""];

Many ways to do it, here is one using character sets:
unichar ch = '5';
BOOL isLetter = [[NSCharacterSet letterCharacterSet] characterIsMember: ch];
BOOL isDigit = [[NSCharacterSet decimalDigitCharacterSet] characterIsMember: ch];
NSLog(#"'%C' is a letter: %d or a digit %d", ch, isLetter, isDigit);

You can use the C functions declared in ctype.h (included by default with Foundation). Be careful with multibyte characters though. Check the man pages.
char c = 'a';
if (isdigit(c)) {
/* ... */
} else if (isalpha(c)) {
/* ... */
}
/* or */
if (isalnum(c))
/* ... */

Checking if a character is a (arabic) number:
NSString* text = [...];
unichar character = [text characterAtIndex:0];
BOOL isNumber = (character >= '0' && character <= '9');
It would be different if you would to know other numeric characters (indian numbers, japanese numbers etc.)
Whether character is a letter depends on what you mean by letter. ASCII letters? Unicode letters?

I'm not too familiar with obj-c, but this sounds like something that can be achieved using a regex pattern.
I did some searching and found this:
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
Try running a regex of "[0-9]" on each character to determine if it is a number.
Save the number to a temporary array, your array should end up with only the numbers.
I would type out the code...but as I said before, I'm not familiar with obj-c. I hope this helps though.

You can check them by comparing the ASCII value for number (0-9 ASCII ranged from 48-57) .. Also you can use NSScanner in Objective C to test for int or a char.

Related

ios method to insert spaces in string

In my app I download a file from amazon's s3, which does not work unless the file name has no spaces in it. For example, one of the files is "HoleByNature". I would like to display this to the user as "Hole By Nature", even though the file name will still have no spaces in it.
I was thinking of writing a method to search through the string starting at the 1st character (not the 0th) and every time I find a capital letter I create a new string with a substring until that index with a space and a substring until the rest.
So I have two questions.
If I use NSString's characterAtIndex, how do I know if that character is capital or not?
Is there a better way to do this?
Thank you!
Works for all unicode uppercase and titlecase letters
- (NSString*) spaceUppercase:(NSString*) text {
NSCharacterSet *set = [NSCharacterSet uppercaseLetterCharacterSet];
NSMutableString *result = [NSMutableString new];
for (int i = 0; i < [text length]; i++) {
unichar c = [text characterAtIndex:i];
if ([set characterIsMember:c] && i!=0){
[result appendFormat:#" %C",c];
} else {
[result appendFormat:#"%C",c];
}
}
return result;
}
I would not go to that approach because I know you can download files with spaces try this please when you construct the NSUrl object
#"my_web_site_url\sub_domain\sub_folder\My%20File.txt
this will download "My File.txt" from the URL provided. so basically you can replace all spaces in the URL with %20
reference:
http://www.w3schools.com/tags/ref_urlencode.asp
Got it working with Jano's answer but using the isupper function as suggested by Richard J. Ross III.
- (NSString*) spaceUppercase:(NSString*) text
{
NSMutableString *result = [NSMutableString new];
[result appendFormat:#"%C",[text characterAtIndex:0]];
for (int i = 1; i < [text length]; i++)
{
unichar c = [text characterAtIndex:i];
if (isupper(c))
{
[result appendFormat:#" %C",c];
}
else
{
[result appendFormat:#"%C",c];
}
}
return result;
}

how to convert lower case character to upper case?

unichar c;
c = [myString characterAtIndex:0];
unichar catchcar = [c lowercaseString];
error : invalid reciever type unicar.
I know lowercaseString is used to covert String not character. Is there any solution?
you could do the following:
unichar catchcar = [[myString lowercaseString] characterAtIndex: 0];
If you have a a character only, do the following:
// given unichar c
unichar catchcar = [[[NSString stringWithCharacters:&c length:1] lowercaseString] characterAtIndex: 0];
The simplest solution for converting case on a single character is to just use the C functions tolower and toupper. Using the code example from the question and rewriting that would give this for conversion to lowercase:
#import <ctype.h>
unichar catchcar = tolower([myString characterAtIndex:0]);
No need to do anything complicated with the NSString API. And no need to make the whole string lowercase first either.
Hope this helps,
Erik
unichar c = [[myString lowercaseString] characterAtIndex:0];
Try this.

How to convert ASCII value to a character in Objective-C?

I was wondering if anyone has the following php function equivalents in Objective-C for iPhone development:
ord() # returns the ASCII value of the first character of a string.
chr() # returns a character from the specified ASCII value.
Many thanks!
This is how you can work with ASCII values and NSString. Note that since NSString is working with unichars, there could be unexpected results for a non ASCII string.
// NSString to ASCII
NSString *string = #"A";
int asciiCode = [string characterAtIndex:0]; // 65
// ASCII to NSString
int asciiCode = 65;
NSString *string = [NSString stringWithFormat:#"%c", asciiCode]; // A
//char to int ASCII-code
char c = 'a';
int ascii_code = (int)c;
//int to char
int i = 65; // A
c = (char)i;

Checking for multiple characters in nsstring

i have a string and i want to check for the multiple characters in this string the following code i working fine for one character how to check for the multiple characters.
NSString *yourString = #"ABCCDEDRFFED"; // For example
NSScanner *scanner = [NSScanner scannerWithString:yourString];
NSCharacterSet *charactersToCount = #"C" // For example
NSString *charactersFromString;
if (!([scanner scanCharactersFromSet:charactersToCount intoString:&charactersFromString])) {
// No characters found
NSLog(#"No characters found");
}
NSInteger characterCount = [charactersFromString length];
UPDATE: The previous example was broken, as NSScanner should not be used like that. Here's a much more straight-forward example:
NSString* string = #"ABCCDEDRFFED";
NSCharacterSet* characters = [NSCharacterSet characterSetWithCharactersInString:#"ABC"];
NSUInteger characterCount;
NSUInteger i;
for (i = 0; i < [yourString length]; i++) {
unichar character = [yourString characterAtIndex:i];
if ([characters characterIsMember:character]) characterCount++;
}
NSLog(#"Total characters = %d", characterCount);
Have a look at the following method in NSCharacterSet:
+ (id)characterSetWithCharactersInString:(NSString *)aString
You can create a character set with more than one character (hence the name character set), by using that class method to create your set. The parameter is a string, every character in that string will end up in the character set.
Also look up NSCountedSet. It can help you keep count of multiple instances of the same character.
For example, from the docs:
countForObject:
Returns the count associated with a given object in the receiver.
- (NSUInteger)countForObject:(id)anObject
Parameters
anObject
The object for which to return the count.
Return Value
The count associated with anObject in the receiver, which can be thought of as the number of occurrences of anObject present in the receiver.

Replace multiple characters in a string in Objective-C?

In PHP I can do this:
$new = str_replace(array('/', ':', '.'), '', $new);
...to replace all instances of the characters / : . with a blank string (to remove them)
Can I do this easily in Objective-C? Or do I have to roll my own?
Currently I am doing multiple calls to stringByReplacingOccurrencesOfString:
strNew = [strNew stringByReplacingOccurrencesOfString:#"/" withString:#""];
strNew = [strNew stringByReplacingOccurrencesOfString:#":" withString:#""];
strNew = [strNew stringByReplacingOccurrencesOfString:#"." withString:#""];
Thanks,
matt
A somewhat inefficient way of doing this:
NSString *s = #"foo/bar:baz.foo";
NSCharacterSet *doNotWant = [NSCharacterSet characterSetWithCharactersInString:#"/:."];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s); // => foobarbazfoo
Look at NSScanner and -[NSString rangeOfCharacterFromSet: ...] if you want to do this a bit more efficiently.
There are situations where your method is good enough I think matt.. BTW, I think it's better to use
[strNew setString: [strNew stringByReplacingOccurrencesOfString:#":" withString:#""]];
rather than
strNew = [strNew stringByReplacingOccurrencesOfString:#"/" withString:#""];
as I think you're overwriting an NSMutableString pointer with an NSString which might cause a memory leak.
Had to do this recently and wanted to share an efficient method:
(assuming someText is a NSString or text attribute)
NSString* someText = #"1232342jfahadfskdasfkjvas12!";
(this example will strip numbers from a string)
[someText stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [someText length])];
Keep in mind that you will need to escape regex literal characters using Obj-c escape character:
(obj-c uses a double backslash to escape special regex literals)
...stringByReplacingOccurrencesOfString:#"[\\\!\\.:\\/]"
What makes this interesting is that NSRegularExpressionSearch option is little used but can lead to some very powerful controls:
You can find a nice iOS regex tutorial here and more on regular expressions at regex101.com
Essentially the same thing as Nicholas posted above, but if you want to remove everything EXCEPT a set of characters (say you want to remove everything that isn't in the set "ABCabc123") then you can do the following:
NSString *s = #"A567B$%C^.123456abcdefg";
NSCharacterSet *doNotWant = [[NSCharacterSet characterSetWithCharactersInString:#"ABCabc123"] invertedSet];
s = [[s componentsSeparatedByCharactersInSet: doNotWant] componentsJoinedByString: #""];
NSLog(#"%#", s); // => ABC123abc
Useful in stripping out symbols and such, if you only want alphanumeric.
+ (NSString*) decodeHtmlUnicodeCharactersToString:(NSString*)str
{
NSMutableString* string = [[NSMutableString alloc] initWithString:str]; // #&39; replace with '
NSString* unicodeStr = nil;
NSString* replaceStr = nil;
int counter = -1;
for(int i = 0; i < [string length]; ++i)
{
unichar char1 = [string characterAtIndex:i];
for (int k = i + 1; k < [string length] - 1; ++k)
{
unichar char2 = [string characterAtIndex:k];
if (char1 == '&' && char2 == '#' )
{
++counter;
unicodeStr = [string substringWithRange:NSMakeRange(i + 2 , 2)]; // read integer value i.e, 39
replaceStr = [string substringWithRange:NSMakeRange (i, 5)]; // #&39;
[string replaceCharactersInRange: [string rangeOfString:replaceStr] withString:[NSString stringWithFormat:#"%c",[unicodeStr intValue]]];
break;
}
}
}
[string autorelease];
if (counter > 1)
return [self decodeHtmlUnicodeCharactersToString:string];
else
return string;
}
Here is an example in Swift 3 using the regularExpression option of replacingOccurances.
Use replacingOccurrences along with a the String.CompareOptions.regularExpression option.
Example (Swift 3):
var x = "<Hello, [play^ground+]>"
let y = x.replacingOccurrences(of: "[\\[\\]^+<>]", with: "7", options: .regularExpression, range: nil)
print(y)
Output:
7Hello, 7play7ground777
If the characters you wish to remove were to be adjacent to each other you could use the
stringByReplacingCharactersInRange:(NSRange) withString:(NSString *)
Other than that, I think just using the same function several times isn't that bad. It is much more readable than creating a big method to do the same in a more generic way.
Create an extension on String...
extension String {
func replacingOccurrences(of strings:[String], with replacement:String) -> String {
var newString = self
for string in strings {
newString = newString.replacingOccurrences(of: string, with: replacement)
}
return newString
}
}
Call it like this:
aString = aString.replacingOccurrences(of:['/', ':', '.'], with:"")