I have an example NSString in iOS
NSString* str = #"-- This is an example string";
I want to get the first alphabet letter. The result of above situation is letter "T" from word "This". Some characters before letter "T" is not alphabet letter so it returns the first alphabet letter is "T".
How can I retrieve it? If the string not contain any alphabet letter, it can return nil.
Besides, the result can be a NSRange
NSRange range = [string rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet]];
First create a NSCharecterSet as a global variable and write this code
-(void)viewDidLoad{
NSCharacterSet *s = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]
s = [s invertedSet];
NSString *myString = #"--- This is a string";
NSArray *arrayOfStrings = [myString componentsSeparatedByString:#" "];
for(int i=0;i<arrayOfStrings.count){
NSString *current = [arrayOfStrings objectAtIndex:i];
char c = [self returnCharacter:current];
if(c == nil){
//that means first word is not with alphabets;
}
else {
NSLog(#"%c",c);
//your output.
}
}
}
And here is the method
-(char)returnChracter:(NSString*)string{
NSRange r = [string rangeOfCharacterFromSet:s];
if (r.location != NSNotFound) {
NSLog(#"the string contains illegal characters");
return nil;
}
else {
//string contains all alphabets
char firstLetter = [string charAtIndex:0];
return firstLetter;
}
}
You can use the following function. Pass a string and get first character as a string.
-(NSString*)getFirstCharacter:(NSString*)string
{
for(int i=0;i<string.length;i++)
{
unichar firstChar = [string characterAtIndex:i];
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
if ([letters characterIsMember:firstChar]) {
return [NSString:stringWithFormat:#"%c",firstChar];
}
}
return nil;
}
Related
How to find word in NSString and check characters before and after this word?
"This pattern has two parts separated by the"
How to find tern and how to check the character before and after
Before word character:"t"
After word character:" "
You can use NSScanner to get indexes of these two characters.
Example:
NSString *string = #"tern";
NSScanner *scanner = [[NSScanner alloc] initWithString:#"This pattern has two parts separated by the"];
[scanner scanUpToString:string intoString:nil];
NSUInteger indexOfChar1 = scanner.scanLocation - 1;
NSUInteger indexOfChar2 = scanner.scanLocation + string.length;
You can also use a rangeOfString method:
Example:
NSRange range = [sourceString rangeOfString:stringToLookFor];
NSUInteger indexOfChar1 = range.location - 1;
NSUInteger indexOfChar2 = range.location +range.length + 1;
Then, when you have indexes, getting the characters is easy:
NSString *firstCharacter = [sourceString substringWithRange:NSMakeRange(indexOfChar1, 1)];
NSString *secondCharacter = [sourceString substringWithRange:NSMakeRange(indexOfChar2, 1)];
Hope this helps.
Here is an implementation using Regular Expressions
NSString *testString= #"This pattern has two parts separated by the";
NSString *regexString = #"(.)(tern)(.)";
NSRegularExpression* exp = [NSRegularExpression
regularExpressionWithPattern:regexString
options:NSRegularExpressionSearch error:&error];
if (error) {
NSLog(#"%#", error);
} else {
NSTextCheckingResult* result = [exp firstMatchInString:testString options:0 range:NSMakeRange(0, [testString length] ) ];
if (result) {
NSRange groupOne = [result rangeAtIndex:1]; // 0 is the WHOLE string.
NSRange groupTwo = [result rangeAtIndex:2];
NSRange groupThree = [result rangeAtIndex:3];
NSLog(#"[%#][%#][%#]",
[testString substringWithRange:groupOne],
[testString substringWithRange:groupTwo],
[testString substringWithRange:groupThree] );
}
}
Results:
[t][tern][ ]
Its better to get pre and post character in NSString to avoid handling of unicode characters.
NSString * testString = #"This pattern has two parts separated by the";
NSString * preString;
NSString * postString;
NSUInteger maxRange;
NSRange range = [testString rangeOfString:#"tern"];
if(range.location == NSNotFound){
NSLog(#"Not found");
return;
}
if (range.location==0) {
preString=nil;
}
else{
preString = [testString substringWithRange:NSMakeRange(range.location-1,1)];
}
maxRange = NSMaxRange(range);
if ( maxRange >=testString.length ) {
postString = nil;
}
else{
postString = [testString substringWithRange:NSMakeRange(range.location+range.length, 1)];
}
I have an NSString that contains a users full name. Some names are in the standard first and last formation (Kyle Begeman) and others are just a single name (TechCrunch).
How would I grab the first name as is and then the first initial of the last name, and if there is only one name, just grab the whole name?
Basically I want the above to be turned into Kyle B. or just TechCrunch depending on the name.
NSString *username = #"Kyle Begeman"
NSString *otherUserName = #"TechCrunch"
converted to
#"Kyle B"
// No conversion because it is a single word name
#"TechCrunch"
Using substringToIndex is how I can grab the first letter in the whole string, and I know there is a way to separate the string by #" " whitespace into an array but I can figure out how to easily produce the result the way it needs to be.
Any help would be great!
(NSString*)firstNameWithInitial:(NSString*)userName {
NSArray *array = [userName componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
array = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF != ''"]];
NSString *firstName = [array objectAtIndex:0];
NSString finalNameString;
if ([array count] > 1) {
NSString *lastNameInitial = [[array objectAtIndex:1] substringToIndex:1];
finalNameString = [firstName stringByAppendingString:[NSString stringWithFormat:#" %#", lastNameInitial]];
else {
finalNameString = firstName;
}
return finalNameString;
}
This function should return what you need. Note that you can modify this to work with people who have more than 2 names, by checking the number of objects in the array.
Find a position pos of the first space in the string. If there is no space, or if the space is the last character of the string, then return the entire string; otherwise, return substring in the range from zero to pos+1, inclusive:
NSRange range = [str rangeOfString:#" "];
if (range.location == NSNotFound || range.location == str.length-1) {
return str;
} else {
return [str substringToIndex:range.location+1];
}
You could use NSScanner to find substrings.
NSString *name = #"Some name";
NSString *firstName;
NSString *lastName;
NSScanner *scanner = [NSScanner scannerWithString:name];
[scanner scanUpToString:#" " intoString:&firstName]; // Scan all characters up to the first space
[scanner scanUpToString:#"" intoString:&lastName]; // Scan remaining characters
if (lastName != nil) {
// It was no space and lastName is empty
} else {
// There was at least one space and lastName contains a string
}
How can I truncate a string at a given length without annihilating a unicode character that might be smack in the middle of my length? How can one determine the index of the beginning of a unicode character in a string so that I can avoid creating ugly strings. The square with half of an A visible is the location of another emoji character which has been truncated.
-(NSMutableAttributedString*)constructStatusAttributedStringWithRange:(CFRange)range
NSString *original = [_postDictionay objectForKey:#"message"];
NSMutableString *truncated = [NSMutableString string];
NSArray *components = [original componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
for(int x=0; x<[components count]; x++)
{
//If the truncated string is still shorter then the range desired. (leave space for ...)
if([truncated length]+[[components objectAtIndex:x] length]<range.length-3)
{
//Just checking if its the first word
if([truncated length]==0 && x==0)
{
//start off the string
[truncated appendString:[components objectAtIndex:0]];
}
else
{
//append a new word to the string
[truncated appendFormat:#" %#",[components objectAtIndex:x]];
}
}
else
{
x=[components count];
}
}
if([truncated length]==0 || [truncated length]< range.length-20)
{
truncated = [NSMutableString stringWithString:[original substringWithRange:NSMakeRange(range.location, range.length-3)]];
}
[truncated appendString:#"..."];
NSMutableAttributedString *statusString = [[NSMutableAttributedString alloc]initWithString:truncated];
[statusString addAttribute:(id)kCTFontAttributeName value:[StyleSingleton streamStatusFont] range:NSMakeRange(0, [statusString length])];
[statusString addAttribute:(id)kCTForegroundColorAttributeName value:(id)[StyleSingleton streamStatusColor].CGColor range:NSMakeRange(0, [statusString length])];
return statusString;
}
UPDATE Thanks to the answer, was able to use one simple function for my needs!
-(NSMutableAttributedString*)constructStatusAttributedStringWithRange:(CFRange)range
{
NSString *original = [_postDictionay objectForKey:#"message"];
NSMutableString *truncated = [NSMutableString stringWithString:[original substringWithRange:[original rangeOfComposedCharacterSequencesForRange:NSMakeRange(range.location, range.length-3)]]];
[truncated appendString:#"..."];
NSMutableAttributedString *statusString = [[NSMutableAttributedString alloc]initWithString:truncated];
[statusString addAttribute:(id)kCTFontAttributeName value:[StyleSingleton streamStatusFont] range:NSMakeRange(0, [statusString length])];
[statusString addAttribute:(id)kCTForegroundColorAttributeName value:(id)[StyleSingleton streamStatusColor].CGColor range:NSMakeRange(0, [statusString length])];
return statusString;
}
NSString has a method rangeOfComposedCharacterSequencesForRange that you can use to find the enclosing range in the string that contains only complete composed characters. For example
NSString *s = #"😄";
NSRange r = [s rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)];
gives the range { 0, 2 } because the Emoji character is stored as two UTF-16 characters (surrogate pair) in the string.
Remark: You could also check if you can simplify your first loop by using
enumerateSubstringsInRange:options:usingBlock
with the NSStringEnumerationByWords option.
"truncate a string at a given length" <-- Do you mean length as in byte length or length as in number of characters? If the latter, then a simple substringToIndex: will suffice (check the bounds first though). If the former, then I'm afraid you'll have to do something like:
NSString *TruncateString(NSString *original, NSUInteger maxBytesToRead, NSStringEncoding targetEncoding) {
NSMutableString *truncatedString = [NSMutableString string];
NSUInteger bytesRead = 0;
NSUInteger charIdx = 0;
while (bytesRead < maxBytesToRead && charIdx < [original length]) {
NSString *character = [original substringWithRange:NSMakeRange(charIdx++, 1)];
bytesRead += [character lengthOfBytesUsingEncoding:targetEncoding];
if (bytesRead <= maxBytesToRead)
[truncatedString appendString:character];
}
return truncatedString;
}
EDIT: Your code can be rewritten as follows:
NSString *original = [_postDictionay objectForKey:#"message"];
NSArray *characters = [[original componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF != ''"]];
NSArray *truncatedCharacters = [characters subarrayWithRange:range];
NSString *truncated = [NSString stringWithFormat:#"%#...", [truncatedCharacters componentsJoinedByString:#" "]];
I'm new to IOS, and was looking for some guidance.
I have a long NSString that I'm parsing out. The beginning may have a few characters of garbage (can be any non-letter character) then 11 digits or spaces, then a single letter (A-Z). I need to get the location of the letter, and get the substring that is 11 characters behind the letter to 1 character behind the letter.
Can anyone give me some guidance on how to do that?
Example: '!!2553072 C'
and I want : '53072 '
You can accomplish this with the regex pattern: (.{11})\b[A-Z]\b
The (.{11}) will grab any 11 characters and the \b[A-Z]\b will look for a single character on a word boundary, meaning it will be surrounded by spaces or at the end of the string. If characters can follow the C in your example then remove the last \b. This can be accomplished in Objective-C like so:
NSError *error;
NSString *example = #"!!2553072 C";
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"(.{11})\\b[A-Z]\\b"
options:NSRegularExpressionCaseInsensitive
error:&error];
if(!regex)
{
//handle error
}
NSTextCheckingResult *match = [regex firstMatchInString:example
options:0
range:NSMakeRange(0, [example length])];
if(match)
{
NSLog(#"match: %#", [example substringWithRange:[match rangeAtIndex:1]]);
}
There may be a more elegant way to do this involving regular expressions or some Objective-C wizardry, but here's a straightforward solution (personally tested).
-(NSString *)getStringContent:(NSString *)input
{
NSString *substr = nil;
NSRange singleLetter = [input rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet]];
if(singleLetter.location != NSNotFound)
{
NSInteger startIndex = singleLetter.location - 11;
NSRange substringRange = NSMakeRange(start, 11);
substr = [tester substringWithRange:substringRange];
}
return substr;
}
You can use NSCharacterSets to split up the string, then take the first remaining component (consisting of your garbage and digits) and get a substring of that. For example (not compiled, not tested):
- (NSString *)parseString:(NSString *)myString {
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
NSArray *components = [myString componentsSeparatedByCharactersInSet:letters];
assert(components.count > 0);
NSString *prefix = components[0]; // assuming relatively new Xcode
return [prefix substringFromIndex:(prefix.length - 11)];
}
//to get rid of all non-Digits in a NSString
NSString *customerphone = CustomerPhone.text;
int phonelength = [customerphone length];
NSRange customersearchRange = NSMakeRange(0, phonelength);
for (int i =0; i < phonelength;i++)
{
const unichar c = [customerphone characterAtIndex:i];
NSString* onechar = [NSString stringWithCharacters:&c length:1];
if(!isdigit(c))
{
customerphone = [customerphone stringByReplacingOccurrencesOfString:onechar withString:#"*" options:0 range:customersearchRange];
}
}
NSString *PhoneAllNumbers = [customerphone stringByReplacingOccurrencesOfString:#"*" withString:#"" options:0 range:customersearchRange];
I received an NSString from the server. Now I want to split it into the substring which I need.
How to split the string?
For example:
substring1:read from the second character to 5th character
substring2:read 10 characters from the 6th character.
You can also split a string by a substring, using NString's componentsSeparatedByString method.
Example from documentation:
NSString *list = #"Norman, Stanley, Fletcher";
NSArray *listItems = [list componentsSeparatedByString:#", "];
NSString has a few methods for this:
[myString substringToIndex:index];
[myString substringFromIndex:index];
[myString substringWithRange:range];
Check the documentation for NSString for more information.
I wrote a little method to split strings in a specified amount of parts.
Note that it only supports single separator characters. But I think it is an efficient way to split a NSString.
//split string into given number of parts
-(NSArray*)splitString:(NSString*)string withDelimiter:(NSString*)delimiter inParts:(int)parts{
NSMutableArray* array = [NSMutableArray array];
NSUInteger len = [string length];
unichar buffer[len+1];
//put separator in buffer
unichar separator[1];
[delimiter getCharacters:separator range:NSMakeRange(0, 1)];
[string getCharacters:buffer range:NSMakeRange(0, len)];
int startPosition = 0;
int length = 0;
for(int i = 0; i < len; i++) {
//if array is parts-1 and the character was found add it to array
if (buffer[i]==separator[0] && array.count < parts-1) {
if (length>0) {
[array addObject:[string substringWithRange:NSMakeRange(startPosition, length)]];
}
startPosition += length+1;
length = 0;
if (array.count >= parts-1) {
break;
}
}else{
length++;
}
}
//add the last part of the string to the array
[array addObject:[string substringFromIndex:startPosition]];
return array;
}