How to compare A to Á on the iPhone - iphone

I need to compare 2 strings, looking at the first letter only.
Is there a method to compare A to Á, and recognize it as A, without the ´?

NSString has a diacritic-insensitive comparison mode which will do what you're after.
// should return NSOrderedSame, i.e. identical
[#"Apple" compare:#"Ápple"
options:NSDiacriticInsensitiveSearch]
If you want it to be case-insensitive as well:
// ditto
[#"APPLE" compare:#"Ápple"
options:NSDiacriticInsensitiveSearch | NSCaseInsensitiveSearch]

Related

Function to split string in matlab and return second number

I have a string and I need two characters to be returned.
I tried with strsplit but the delimiter must be a string and I don't have any delimiters in my string. Instead, I always want to get the second number in my string. The number is always 2 digits.
Example: 001a02.jpg I use the fileparts function to delete the extension of the image (jpg), so I get this string: 001a02
The expected return value is 02
Another example: 001A43a . Return values: 43
Another one: 002A12. Return values: 12
All the filenames are in a matrix 1002x1. Maybe I can use textscan but in the second example, it gives "43a" as a result.
(Just so this question doesn't remain unanswered, here's a possible approach: )
One way to go about this uses splitting with regular expressions (MATLAB's strsplit which you mentioned):
str = '001a02.jpg';
C = strsplit(str,'[a-zA-Z.]','DelimiterType','RegularExpression');
Results in:
C =
'001' '02' ''
In older versions of MATLAB, before strsplit was introduced, similar functionality was achieved using regexp(...,'split').
If you want to learn more about regular expressions (abbreviated as "regex" or "regexp"), there are many online resources (JGI..)
In your case, if you only need to take the 5th and 6th characters from the string you could use:
D = str(5:6);
... and if you want to convert those into numbers you could use:
E = str2double(str(5:6));
If your number is always at a certain position in the string, you can simply index this position.
In the examples you gave, the number is always the 5th and 6th characters in the string.
filename = '002A12';
num = str2num(filename(5:6));
Otherwise, if the formating is more complex, you may want to use a regular expression. There is a similar question matlab - extracting numbers from (odd) string. Modifying the code found there you can do the following
all_num = regexp(filename, '\d+', 'match'); %Find all numbers in the filename
num = str2num(all_num{2}) %Convert second number from str

Capitalizing only the first letters without changing any numbers or punctuation

I would like to modify a string that will have make the first letter capitalized and all other letters lower cased, and anything else will be unchanged.
I tried this:
function new_string=switchCase(str1)
%str1 represents the given string containing word or phrase
str1Lower=lower(str1);
spaces=str1Lower==' ';
caps1=[true spaces];
%we want the first letter and the letters after space to be capital.
strNew1=str1Lower;
strNew1(caps1)=strNew1(caps1)-32;
end
This function works nicely if there is nothing other than a letter after space. If we have anything else for example:
str1='WOW ! my ~Code~ Works !!'
Then it gives
new_string =
'Wow My ^code~ Works !'
However, it has to give (according to the requirement),
new_string =
'Wow! My ~code~ Works !'
I found a code which has similarity with this problem. However, that is ambiguous. Here I can ask question if I don't understand.
Any help will be appreciated! Thanks.
Interesting question +1.
I think the following should fulfil your requirements. I've written it as an example sub-routine and broken down each step so it is obvious what I'm doing. It should be straightforward to condense it into a function from here.
Note, there is probably also a clever way to do this with a single regular expression, but I'm not very good with regular expressions :-) I doubt a regular expression based solution will run much faster than what I've provided (but am happy to be proven wrong).
%# Your example string
Str1 ='WOW ! my ~Code~ Works !!';
%# Convert case to lower
Str1 = lower(Str1);
%# Convert to ascii
Str1 = double(Str1);
%# Find an index of all locations after spaces
I1 = logical([0, (Str1(1:end-1) == 32)]);
%# Eliminate locations that don't contain lower-case characters
I1 = logical(I1 .* ((Str1 >= 97) & (Str1 <= 122)));
%# Check manually if the first location contains a lower-case character
if Str1(1) >= 97 && Str1(1) <= 122; I1(1) = true; end;
%# Adjust all appropriate characters in ascii form
Str1(I1) = Str1(I1) - 32;
%# Convert result back to a string
Str1 = char(Str1);

Confusion with case used by CFURLCreateStringByAddingPercentEscapes encoding

I want URL encoding to be done. My input string is "ChBdgzQ3qUpNRBEHB+bOXQNjRTQ="
I get an output as "ChBdgzQ3qUpNRBEHB%2BbOXQNjRTQ%3D" which is totally correct except the case which gets encoded.
Ideally, it should have been "ChBdgzQ3qUpNRBEHB%2bbOXQNjRTQ%3d" instead of the output I get.
i.e I should have got %2b and %3d instead of %2B and %3D.
Could this be done?
The code I used is as below :
NSString* inputStr = #"ChBdgzQ3qUpNRBEHB+bOXQNjRTQ=";
NSString* outputStr = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)inputStr,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
Another perhaps more elegant but slower way would be to loop over your string, converting each character in the string one by one (so you would get the length of your string, then get a substring from it from location 0 to length-1, with one character each time, then translate just that substring. If the returned string has a length > 1, then CFURLCreateStringByAddingPercentEscapes encoded the character, and you can safely turn the case into lower case.
In all cases you append the returned (and possibly modified) string to a mutable string, and when done you have exactly what you want for any possible string. Even though this would appear to be a real processor hog, the reality is you would probably never notice the extra consumed cycles.
Likewise, a second approach would be to just convert your whole string first, then copy it byte by byte to a mutable string, and if you find a "%", then turn the next two characters into lower case. Just a slightly different way to slice the problem.
You can use a regular expression to perform the post operation:
NSMutableString *finalStr = outputStr.mutableCopy;
NSRegularExpression *re = [[NSRegularExpression alloc] initWithPattern:#"(?<=%)[0-9A-F]{2}" options:0 error:nil];
for (NSTextCheckingResult *match in [re matchesInString:escaped options:0 range:NSMakeRange(0, escaped.length)]) {
[finalStr replaceCharactersInRange:match.range withString:[[escaped substringWithRange:match.range] lowercaseString]];
}
The code uses this regular expression:
(<?=%)[0-9A-F]{2}
It matches two hexadecimal characters, only if preceded by a percent sign. Each match is then iterated and replaced within a mutable string. We don't have to worry about offset changes because the replacement string is always the same length.

How do I access the nth character(s) in an NSString?

I've got HEX colors as NSStrings and want to check if a particular string contains an F at the first, third, or fifth character, but to ignore it if it contains an F at the second, fourth or sixth character.
This is to identify if the color in question is a light color or not.
I searched for this, but only found answers regarding how to find character ranges.
You can use the characterAtIndex member of NSString.
char fifthChar = [yourString characterAtIndex:5];
As #Daniel Pereira says, you can use the -[NSString characterAtIndex:] method to check characters.
NSString *string = /* Assume this exists */;
if ([string characterAtIndex: 1] == 'F' || \
[string characterAtIndex: 3] == 'F' || \
[string characterAtIndex: 5] == 'F')
{
// F at odd-indexed character
}
else
{
// Do other stuff here...
}
Have you tried to use characterAtIndex? You can use the method to retrieve the string at the first, third and fifth character (of course one at a time) and compare it with F.
Note that all your HEX colors must be 6 characters. Sometimes, you can represent a color with only three hex values (eg. FFF would still give you white in HTML). So if your color is represented using three chars only, and you try to get the char at index 5, the method will throw an 'out of range' exception.

How can accented strings be sorted in Objective-c in a way that the accented always follows the base character?

I try to sort a list of strings alphabetically in Objective-C. Since the list is hungarian, it contains accented characters (they are part of the "official" hungarian alphabet), and they should be ordered as: a á b c d e é ...
The problem is that iOS orders that list as the accents wouldn't exist, so these three lines are sorted as:
abc
ábc
acc
But sould be sorted as:
abc
acc
ábc
I tried to sort the string like this:
static NSStringCompareOptions comparisonOptions =
NSCaseInsensitiveSearch | NSNumericSearch |
NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSRange string1Range = NSMakeRange(0, 4);
NSComparisonResult res = [#"Abel" compare:#"Áael" options:comparisonOptions range:string1Range locale:[[NSLocale alloc] initWithLocaleIdentifier:#"hu_HU"]];
switch (res) {
case NSOrderedAscending:
NSLog(#"Ascending");
break;
case NSOrderedDescending:
NSLog(#"Descending");
break;
default:
NSLog(#"Same");
break;
}
The result is descending, so it wants to swap the two to be in order, but it shouldn't.
There is a NSComparisionOption element called NSDiacriticInsensitiveSearch which means - as the documentation states - that the comparison should ignore the accents and compare as if it were the base character. Unfortunately, the comparison seems to work that way even without defining this option.
I use iOS version 4.3 for iPhone.