Count characters before some string iOS - ios

I need to count characters in string before some string and after some string. For example, I have string "This is example string" and I need to know howmany characters are before word "example" (it is 8 chars in this case) and how many characters are after word "example" (7 in that case...). My idea was to loop that string and count every character, but how to stop it before that requied word? Thanks for every idea!

check this out
NSString *sample = #"This is example string";
NSRange b = [sample rangeOfString:#"example"];
if (b.location != NSNotFound) {
NSLog(#"%d characters before", b.location);
NSLog(#"%d characters after", [sample length] - b.location - b.length);
}

Related

Way to detect character that takes up more than one index spot in an NSString?

I'm wondering, is there a way to detect a character that takes up more than 1 index spot in an NSString? (like an emoji). I'm trying to implement a custom text view and when the user pushes delete, I need to know if I should delete only the previous one index spot or more.
Actually NSString use UTF-16.So it is quite difficult to work with characters which takes two UTF-16 charater(unichar) or more.But you can do with rangeOfComposedCharacterSequenceAtIndexto get range and than delete.
First find the last character index from string
NSUInteger lastCharIndex = [str length] - 1;
Than get the range of last character
NSRange lastCharRange = [str rangeOfComposedCharacterSequenceAtIndex: lastCharIndex];
Than delete with range from character (If it is of two UTF-16 than it deletes UTF-16)
deletedLastCharString = [str substringToIndex: lastCharRange.location];
You can use this method with any type of characters which takes any number of unichar
For one you could transform the string to a sequence of characters using [myString UTF8String] and you can then check if the character has its first bit set to one or zero. If its one then this is a UTF8 character and you can then check how many bytes are there to this character. Details about UTF8 can be found on Wikipedia - UTF8. Here is a simple example:
NSString *string = #"ČTest";
const char *str = [string UTF8String];
NSMutableString *ASCIIStr = [NSMutableString string];
for (int i = 0; i < strlen(str); ++i)
if (!(str[i] & 128))
[ASCIIStr appendFormat:#"%c", str[i]];
NSLog(#"%#", ASCIIStr); //Should contain only ASCII characters

getting certain portion of nsstring

I have string as follows in objective c
NSString *str = #"access_token=E2JmCPLtVySGn-cGGJGGnQ&email=abc#gmail.com";
How can i get only E2JmCPLtVySGn-cGGJGGnQ ?
You can use a Regular Expression (RegEx) to find character patterns.
The pattern matching syntax can be found in the ICU User Guide Regular Expressions
In the example the pattern is: find the first "=" and all characters up to but not including the character "&". In the pattern '(?<=access_token=)" is a look-behind assertion meaning that the "access_token=" must precede the matched text, "[^&]+" the brackets the "[]" mean a character class, the "^" al but the following character, the "+" means one or more.
NSString *str = #"access_token=E2JmCPLtVySGn-cGGJGGnQ&email=abc#gmail.com";
NSString *regexPattern = #"(?<=access_token=)[^&]+";
NSString *found = nil;
NSRange range = [str rangeOfString:regexPattern options:NSRegularExpressionSearch];
if (range.location != NSNotFound) {
found = [str substringWithRange:range];
}
NSLog(#"Range: %#", NSStringFromRange(range));
NSLog(#"found: %#", found);
NSLog output if found:
Range: {13, 22}
found: E2JmCPLtVySGn-cGGJGGnQ
There is a method of the NSString class called rangeOfString: that returns an NSRange struct. If you know that your returned value always has the text access_token= and also includes &email and the format is always the same, you can use this rangeOfString: method to sniff out the token.
NSRange accessTokenRange = [str rangeOfString:#"access_token="];
//this would return (0,13) for index:0, length: 13
NSRange emailRange = [str rangeOfString:#"&email="];
//this would return (34,7)
NSInteger tokenLength = ( emailRange.location + 1 ) - accessTokenRange.length;
//the point where &email begins is at index 34, but it starts at 0
//so it's actually the 35th character
//the access_token= string is 13 characters long, so 35-13 = 22
//so you know that the actual token value is 22 characters long
NSRange trueTokenRange = NSMakeRange(accessTokenRange.length,tokenLength);
NSString *tokenSubstring = [str substringWithRange:trueTokenRange];
I don't think my math is off, zero indexing can introduce off by 1 errors if you're not careful, I usually have NSLog going on each range so I can double check where I need to add or subtract 1. But essentially you'll be starting at the 14th character, which is index 13 of the string, and reading the next 22 characters.

Check to see if UITextField has a numeric value greater than 0

I have a UITextField and I only want a number greater than 0 ( I don't want non-numeric characters or the value 0 )
This is how I check to see if it is empty:
if(seizure.text.length==0)
This is how I check to see if it is equal to 0:
else if(seizure.text doubleValue]==0)
How can I check for non-numeric characters?
First check to see if you have any characters in the string, then check to make sure that it only contains numeric characters, and finally check to see if the value is greater than 0:
if (seizure.text.length > 0)
{
NSCharacterSet *nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([seizure.text rangeOfCharacterFromSet:nonNumbers].location == NSNotFound)
{
if ([seizure.text doubleValue] > 0)
{
// Text Field contains a numeric value greater than 0
NSLog(#"Good number.");
return;
}
}
}
// If we make it to here, it does not meet your requirements.
NSLog(#"Bad Number.");
NSScanner will do the job nicely here. Unlike -[NSString doubleValue], its scanDouble: can parse and then also tell you whether it consumed the entire string, so you will know that there are non-numerical characters present.
Demonstration on some test cases. See the comments for descriptions of the expected results.
NSArray * texts = #[// First four unacceptable because non-numeric
#"", #"Hello, world!", #"1.0 excelsior", #"Jiminy 1.0 Crickets",
// These three unacceptable because 0 or less
#"0.0" #"0", #"-2048",
// Last three are good
#"3.14159", #"1", #"10000000000.0"];
for( NSString * text in texts ){
NSScanner * scanner = [NSScanner scannerWithString:text];
double val;
[scanner scanDouble:&val];
// Scanned the whole string and ended up with a positive value
if( [scanner isAtEnd] && val > 0 ){
NSLog(#"'%#'? I accept.", text);
}
else {
NSLog(#"'%#' is no good.", text);
}
}
[seizure.text doubleValue] == 0 will be true either if seizure.text is a textual representation of zero or if it doesn't contain a valid textual representation of a number (see the documentation for doubleValue).
In other words if this expression is false then you have a string value which starts with a number. However you still don't know if you string value contains only a number, e.g. [#"2.5 miles" doubleValue] has the value 2.5. If you need to handle strings like this you should look at NSScanner.

iOS: print unicode character in decimal notation

How would I print a string with 1 letter in a decimal form?
I need to get unique integer for a character and convert it to string.
NSString* letter = #"a"; // ---> to #"97"
unichar c = [letter characterAtIndex:0];
NSString *charAsNum = [NSString stringWithFormat:#"%d",c];

Rendering an ASCII art string with newline characters and backslashes

I am making an app where there is a requirement to store ASCII art into a database. I store the strings in the below format.
"___________\n |---------|-O\n/___________\\n|______________|\n\____________/"
When I retrieve the data and display it in a label, I want the newline characters and backslashes to be parsed so as to display the real shape of the ASCII art.
How should I parse this kind of strings?
NSString has a method to do what you want, which is to replace a litteral \n, with a newline character (which is symbolized as \n). In a c-format string you can use a double slash to let the library know the second slach is a real one and not an escape symbol. So this should work assuming you have been able to load your data from sqlite into an NSString:
newString = [yourStringFromSQLite stringByReplacingOccurrencesOfString:#"\\n" withString:#"\n"];
If you are using \n just for creating new lines then instead of that just keep space while inserting value in database and set following properties for label ->
1)keep width just to fit first word.
2)linebreakmode to wordwrap (so as width will not be available it will wrap next word to new line)
3)set no. of lines to 0
Hope this will help.
try to use the scanner for remove the html entities
- (NSString *)flattenHTML:(NSString *)html trimWhiteSpace:(BOOL)trim {
NSScanner *theScanner;
NSString *text = nil;
theScanner = [NSScanner scannerWithString:html];
while ([theScanner isAtEnd] == NO) {
[theScanner scanUpToString:#"<" intoString:NULL] ;
[theScanner scanUpToString:#">" intoString:&text] ;
html = [html stringByReplacingOccurrencesOfString:[ NSString stringWithFormat:#"%#>", text] withString:#" "];
}
return trim ? [html stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] : html;
}
and call this method where your trimmed string need to display

Resources