I need to remove all emoijs from a NSString.
So far i am using this NSString extension ...
- (NSString*)noEmoticon {
static NSMutableCharacterSet *emoij = NULL;
if (emoij == NULL) {
emoij = [[NSMutableCharacterSet alloc] init];
// unicode range of old emoijs
[emoij removeCharactersInRange:NSMakeRange(0xE000, 0xE537 - 0xE000)];
}
NSRange range = [self rangeOfCharacterFromSet:emoij];
if (range.length == 0) {
return self;
}
NSMutableString *cleanedString = [self mutableCopy];
while (range.length > 0) {
[cleanedString deleteCharactersInRange:range];
range = [cleanedString rangeOfCharacterFromSet:emoij];
}
return cleanedString;
}
... but that does not work at all. The range.length is always 0.
So the general question is : How can i remove a range of unicode characters from a NSString?
Thanks a lot.
It seems to me that in the above code the emoij variable is eventually an empty set. Didn't you mean to addCharactersInRange: rather than to removeCharactersInRange:?
Related
Code Snippet:
NSString *tempStr = self.consumerNumber.text;
if ([tempStr hasPrefix:#"0"] && [tempStr length] > 1) {
tempStr = [tempStr substringFromIndex:1];
[self.consumerNumbers addObject:tempStr];>
}
I tried those things and removing only one zero. how to remove more then one zero
Output :001600240321
Expected result :1600240321
Any help really appreciated
Thanks in advance !!!!!
Try to use this one
NSString *stringWithZeroes = #"001600240321";
NSString *cleanedString = [stringWithZeroes stringByReplacingOccurrencesOfString:#"^0+" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, stringWithZeroes.length)];
NSLog(#"Clean String %#",cleanedString);
Clean String 1600240321
convert string to int value and re-assign that value to string,
NSString *cleanString = [NSString stringWithFormat:#"%d", [string intValue]];
o/p:-1600240321
You can add a recursive function that is called until the string begin by something else than a 0 :
-(NSString*)removeZerosFromString:(NSString *)anyString
{
if ([anyString hasPrefix:#"0"] && [anyString length] > 1)
{
return [self removeZerosFromString:[anyString substringFromIndex:1]];
}
else
return anyString;
}
so you just call in your case :
NSString *tempStr = [self removeZerosFromString:#"000903123981000"];
NSString *str = #"001600240321";
NSString *newStr = [#([str integerValue]) stringValue];
If the NSString contains numbers only.
Other wise use this:
-(NSString *)stringByRemovingStartingZeros:(NSString *)string
{
NSString *newString = string;
NSInteger count = 0;
for(int i=0; i<[string length]; i++)
{
if([[NSString stringWithFormat:#"%c",[string characterAtIndex:i]] isEqualToString:#"0"])
{
newString = [newString stringByReplacingCharactersInRange:NSMakeRange(i-count, 1) withString:#""];
count++;
}
else
{
break;
}
}
return newString;
}
Simply call this method:-
NSString *stringWithZeroes = #"0000000016909tthghfghf";
NSLog(#"%#", [self stringByRemovingStartingZeros:stringWithZeroes]);
OutPut: 16909tthghfghf
Try the `stringByReplacingOccurrencesOfString´ methode like this:
NSString *new = [old stringByReplacingOccurrencesOfString: #"0" withString:#""];
SORRY: This doesn't help you due to more "0" in the middle part of your string!
Something strange is going on. When I reassign an NSString to my subString variable near the bottom of my code. It seems that the value of subString is empty in the output. I don't know if objectAtIndex is returning something weird or it's a memory problem. If I create a new variable instead of reassigning the value of subString, I can print see the correct value in the output console. If anyone could help me figure this out. It'd be greatly appreciated.
NSString *subString = #"";
if ([text length] > 0)
{
UITextRange *selectedRange = [_textView selectedTextRange];
UITextPosition *cursorPosition = [_textView positionFromPosition:selectedRange.start offset:0];
UITextRange *subTextRange = [_textView textRangeFromPosition:_textView.beginningOfDocument toPosition:cursorPosition];
subString = [textView textInRange:subTextRange];
}
NSLog(subString);
NSLog(#" %s", [subString hasSuffix:#" "] ? "TRUE" : "FALSE");
BOOL hasSpaceSuffix = [subString hasSuffix:#" "];
NSLog(#" %s", _taggingInProgress ? "TRUE" : "FALSE");
NSArray *substringArray = [[subString componentsSeparatedByString:#" "] retain];
if ([substringArray count] > 1) {
int index = [substringArray count];
if ([[substringArray objectAtIndex:index-1] isEqualToString:#" "])
{
NSLog(#"1st");
subString = [substringArray objectAtIndex:index-2];
NSLog(subString);
}
else
{
NSLog(#"2nd");
subString = [substringArray objectAtIndex:index-1];
NSLog(subString);
}
NSLog(#"AFTER");
NSLog(subString);
}
I think you need to use:
subString = [NSString stringWithString:[substringArray objectAtIndex:index]];
...fixed...
I have a number stored in an NSMutableString instance which I want to auto format with comma delimiters and then display the result in a UITextField.
I've tried using NSNumberFormatter to format as currency, but I don't want it to show decimals if the original NSMutableString doesn't contain a decimal place.
For example:
If the NSMutableString contains "1234567", it should format as "1,234,567".
If the NSMutableString contains "1234567.1", it should format as "1,234,567.1"
If the NSMutableString contains "1234567.12", it should format as "1,234,567.12"
The maximum decimals that the NSMutableString will contain is 2.
Any help is greatly appreciated.
Thanks!
Keep in mind that you should really be localizing this if you are interacting with users on this, however here is one way to do it:
- (NSString *)formatString:(NSString *)string {
// Strip out the commas that may already be here:
NSString *newString = [string stringByReplacingOccurrencesOfString:#"," withString:#""];
if ([newString length] == 0) {
return nil;
}
// Check for illegal characters
NSCharacterSet *disallowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:#"0123456789."] invertedSet];
NSRange charRange = [newString rangeOfCharacterFromSet:disallowedCharacters];
if ( charRange.location != NSNotFound) {
return nil;
}
// Split the string into the integer and decimal portions
NSArray *numberArray = [newString componentsSeparatedByString:#"."];
if ([numberArray count] > 2) {
// There is more than one decimal point
return nil;
}
// Get the integer
NSString *integer = [numberArray objectAtIndex:0];
NSUInteger integerDigits = [integer length];
if (integerDigits == 0) {
return nil;
}
// Format the integer.
// You can do this by first converting to a number and then back to a string,
// but I would rather keep it as a string instead of doing the double conversion.
// If performance is critical, I would convert this to a C string to do the formatting.
NSMutableString *formattedString = [[NSMutableString alloc] init];
if (integerDigits < 4) {
[formattedString appendString:integer];
} else {
// integer is 4 or more digits
NSUInteger startingDigits = integerDigits % 3;
if (startingDigits == 0) {
startingDigits = 3;
}
[formattedString setString:[integer substringToIndex:startingDigits]];
for (NSUInteger index = startingDigits; index < integerDigits; index = index + 3) {
[formattedString appendFormat:#",%#", [integer substringWithRange:NSMakeRange(index, 3)]];
}
}
// Add the decimal portion if there
if ([numberArray count] == 2) {
[formattedString appendString:#"."];
NSString *decimal = [numberArray objectAtIndex:1];
if ([decimal length] > 0) {
[formattedString appendString:decimal];
}
}
return formattedString;
}
// Test cases:
NSLog(#"%#", [self formatString:#"123456"]);
NSLog(#"%#", [self formatString:#"1234567."]);
NSLog(#"%#", [self formatString:#"12345678.1"]);
NSLog(#"%#", [self formatString:#"123456789.12"]);
// Output:
123,456
1,234,567.
12,345,678.1
123,456,789.12
I think this should do it -- I added an if statement to check if there is a decimal point in the typed in value. "Output" in this example is a property that I have bound to the value of a text field to show the result.
-(IBAction)doConversion:(id)sender{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init];
[formatter setMaximumFractionDigits:2];
[formatter setUsesGroupingSeparator:YES];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
double entryFieldFloat = [entryField doubleValue];
if ([entryField.stringValue rangeOfString:#"."].length == 1) {
formatter.alwaysShowsDecimalSeparator = YES;
self.output =[formatter stringFromNumber:[NSNumber numberWithDouble:entryFieldFloat]];
}else{
formatter.alwaysShowsDecimalSeparator = NO;
self.output =[formatter stringFromNumber:[NSNumber numberWithDouble:entryFieldFloat]];
}
}
Just call this method to be simple:
public static String GetCommaSeparatedCount(this Int32 Count)
{
// Check for The less-than character (<) is converted to <
String result = String.Format("{0:#,##0}", Count);
return result;
}
You're looking for the -setMinimumFractionDigits: method on NSNumberFormatter. Set that to 0 and it'll only display the decimal point if there's anything to put after it.
I have 4 text fields in my application.
I validate my textfields as textfield allow 0,1,...9 and .,for that i write code as fallows
- (IBAction) textfield:(id)sender {
if ([textfield.text length] > 0) {
if ([textfield.text length] > 10){
textfield.text = [textfield.text substringWithRange:NSMakeRange(0, 10)];
}
else {
//retrieve last character input from texfield
int I01 = [homevalue.text length];
int Char01 = [homevalue.text characterAtIndex:I01-1];
//check and accept input if last character is a number from 0 to 9
if ( (Char01 < 46) || (Char01 > 57) || (Char01 == 47) ) {
if (I01 == 1) {
textfield.text = nil;
}
else {
textfield.text = [homevalue.text substringWithRange:NSMakeRange(0, I01-1)];
}
}
}
}
}
It works fine, Now i need to validate that . allows only once with in the textfield.
eg: 123.45
According to my code if i place again . it is allowed.
eg:123.45.678
But it wont allowed once i place . ,that textfield wont allowed.
ed:123.45678.
How can i done this,
can any one pls help me.
Thank u in advance.
Try this predicate for texts that start with a number like "23.67"
NSString *decimalRegex = #"[0-9]+([.]([0-9]+)?)?"; // #"[0-9]+[.][0-9]+";
NSPredicate *decimalTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", decimalRegex];
BOOL isValidDecimal = [decimalTest evaluateWithObject:[textField text]];
If you want to allow "." at the fist place like ".95" use the following regex,
NSString *decimalRegex = #"[0-9]*([.]([0-9]+)?)?"; //#"[0-9]*[.][0-9]+";
Your code should look like this,
- (IBAction)textfield:(id)sender {
int textLength = [[textfield text] length];
if (textLength > 0) {
NSString *decimalRegex = #"[0-9]+([.]([0-9]+)?)?"; //#"[0-9]+[.][0-9]+";
NSPredicate *decimalTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", decimalRegex];
BOOL isValidDecimal = [decimalTest evaluateWithObject:[textField text]];
if (!isValidDecimal) {
NSString *text = [[textField text] substringToIndex:textLength - 1];
[textfield setText:text]
}
}
}
I guess this should work! Give it a try!
Well you can use this method
- (NSRange)rangeOfCharacterFromSet:(NSCharacterSet *)aSet options:(NSStringCompareOptions)mask range:(NSRange)aRange
on textfield.text as its a NSString only
i'm trying to build a function that will tell me the range of a string at an occurrence.
For example if I had the string "hello, hello, hello", I want to know the range of hello at it's, lets say, third occurrence.
I've tried building this simple function, but it doesn't work.
Note - the top functions were constructed at an earlier date and work fine.
Any help appreciated.
- (NSString *)stringByTrimmingString:(NSString *)stringToTrim toChar:(NSUInteger)toCharacterIndex {
if (toCharacterIndex > [stringToTrim length]) return #"";
NSString *devString = [[[NSString alloc] init] autorelease];
for (int i = 0; i <= toCharacterIndex; i++) {
devString = [NSString stringWithFormat:#"%#%#", devString, [NSString stringWithFormat:#"%c", [stringToTrim characterAtIndex:(i-1)]]];
}
return devString;
[devString release];
}
- (NSString *)stringByTrimmingString:(NSString *)stringToTrim fromChar:(NSUInteger)fromCharacterIndex {
if (fromCharacterIndex > [stringToTrim length]) return #"";
NSString *devString = [[[NSString alloc] init] autorelease];
for (int i = (fromCharacterIndex+1); i <= [stringToTrim length]; i++) {
devString = [NSString stringWithFormat:#"%#%#", devString, [NSString stringWithFormat:#"%c", [stringToTrim characterAtIndex:(i-1)]]];
}
return devString;
[devString release];
}
- (NSRange)rangeOfString:(NSString *)substring inString:(NSString *)string atOccurence:(int)occurence {
NSString *trimmedString = [inString copy]; //We start with the whole string.
NSUInteger len, loc, oldLength;
len = 0;
loc = 0;
NSRange tempRange = [string rangeOfString:substring];
len = tempRange.length;
loc = tempRange.location;
for (int i = 0; i != occurence; i++) {
NSUInteger endOfWord = len+loc;
trimmedString = [self stringByTrimmingString:trimmedString fromChar:endOfWord];
oldLength += [[self stringByTrimmingString:trimmedString toChar:endOfWord] length];
NSRange tmp = [trimmedString rangeOfString:substring];
len = tmp.length;
loc = tmp.location + oldLength;
}
NSRange returnRange = NSMakeRange(loc, len);
return returnRange;
}
Instead of trimming the string a bunch of times (slow), just use rangeOfString:options:range:, which searches only within the range passed as its third argument. See Apple's documentation.
So try:
- (NSRange)rangeOfString:(NSString *)substring
inString:(NSString *)string
atOccurence:(int)occurence
{
int currentOccurence = 0;
NSRange rangeToSearchWithin = NSMakeRange(0, string.length);
while (YES)
{
currentOccurence++;
NSRange searchResult = [string rangeOfString: substring
options: NULL
range: rangeToSearchWithin];
if (searchResult.location == NSNotFound)
{
return searchResult;
}
if (currentOccurence == occurence)
{
return searchResult;
}
int newLocationToStartAt = searchResult.location + searchResult.length;
rangeToSearchWithin = NSMakeRange(newLocationToStartAt, string.length - newLocationToStartAt);
}
}
You need to rework the whole code. While it may seem to work, it's poor coding and plain wrong, like permanently reassigning the same variable, initializing but reassigning one line later, releasing after returning (which will never work).
For your question: Just use rangeOfString:options:range:, and do this the appropriate number of times while just incrementing the starting point.