Find one string in another with case insensitive in Objective-C - objective-c

My question is similar to How do I check if a string contains another string in Objective-C?
How can I check if a string (NSString) contains another smaller string but with ignoring case?
NSString *string = #"hello bla bla";
I was hoping for something like:
NSLog(#"%d",[string containsSubstring:#"BLA"]);
Anyway is there any way to find if a string contains another string with ignore case ? But please do not convert both strings to UpperCase or to LowerCase.

As similar to the answer provided in the link, but use options.
See - (NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask in Apple doc
NSString *string = #"hello bla bla";
if ([string rangeOfString:#"BLA" options:NSCaseInsensitiveSearch].location == NSNotFound)
{
NSLog(#"string does not contain bla");
}
else
{
NSLog(#"string contains bla!");
}

From iOS 8 you can add the containsString: or localizedCaseInsensitiveContainsString method to NSString.
if ([string localizedCaseInsensitiveContainsString:#"BlA"]) {
NSLog(#"string contains Case Insensitive bla!");
} else {
NSLog(#"string does not contain bla");
}

NSString *string = #"hello BLA";
if ([string rangeOfString:#"bla" options:NSCaseInsensitiveSearch].location == NSNotFound) {
NSLog(#"string does not contain bla");
} else {
NSLog(#"string contains bla!");
}

The method
[string rangeOfString:#"bla" options:NSCaseInsensitiveSearch];
should help you.

You can use -(NSRange)rangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask; to get a range for a substring, the mask parameter is used to specify case insensitive match.
Example :
NSRange r = [str rangeOfString:#"BLA"
options:NSCaseInsensitiveSearch];
As stated in the documentation, the method returns a range like {NSNotFound, 0} when the substring isn't found.
BOOL b = r.location == NSNotFound;
Important this method raises an exception if the string is nil.

For Swift 4:
extension String {
func containsCaseInsensitive(string : String) -> Bool {
return self.localizedCaseInsensitiveContains(string)
}
}
Usage:
print("Hello".containsCaseInsensitive(string: "LLO"))
Output:
true

Related

search if NSString contains value

I have some string value which constructed from a few characters , and i want to check if they exist in another NSString, without case sensitive, and spaces .
Example code :
NSString *me = #"toBe" ;
NSString *target=#"abcdetoBe" ;
//than check if me is in target.
Here i will get true because me exist in target .
How can i check for such condition ?
I have read How do I check if a string contains another string in Objective-C? but its case sensitive and i need to find with no case sensitive..
Use the option NSCaseInsensitiveSearch with rangeOfString:options:
NSString *me = #"toBe" ;
NSString *target = #"abcdetobe" ;
NSRange range = [target rangeOfString: me options: NSCaseInsensitiveSearch];
NSLog(#"found: %#", (range.location != NSNotFound) ? #"Yes" : #"No");
if (range.location != NSNotFound) {
// your code
}
NSLog output:
found: Yes
Note: I changed the target to demonstrate that case insensitive search works.
The options can be "or'ed" together and include:
NSCaseInsensitiveSearch
NSLiteralSearch
NSBackwardsSearch
NSAnchoredSearch
NSNumericSearch
NSDiacriticInsensitiveSearch
NSWidthInsensitiveSearch
NSForcedOrderingSearch
NSRegularExpressionSearch
-(BOOL)substring:(NSString *)substr existsInString:(NSString *)str {
if(!([str rangeOfString:substr options:NSCaseInsensitiveSearch].length==0)) {
return YES;
}
return NO;
}
usage:
NSString *me = #"toBe";
NSString *target=#"abcdetoBe";
if([self substring:me existsInString:target]) {
NSLog(#"It exists!");
}
else {
NSLog(#"It does not exist!");
}
As with the release of iOS8, Apple added a new method to NSStringcalled localizedCaseInsensitiveContainsString. This will exactly do what you want:
Swift:
let string: NSString = "ToSearchFor"
let substring: NSString = "earch"
string.localizedCaseInsensitiveContainsString(substring) // true
Objective-C:
NSString *string = #"ToSearchFor";
NSString *substring = #"earch";
[string localizedCaseInsensitiveContainsString:substring]; //true

Type checking string value like "string" & "integer" & "boolean"ยท

I have strings containing names of types. Therefore it is not instances on the types, I only have the string value describing the type and an input text in string.
NSString *text = #"1234";
NSString *type = #"integer";
NSString *text = #"hello there";
NSString *type = #"string";
NSString *text = #"true";
NSString *type = #"bool";
How would you check if it is a valid type from the tekst.
Would NSRegularExpression be the right way or how would you do it?
I have the following lines of code.
- (NSInteger)getStringType:(NSString *)value :(BOOL)a {
if ([value isEqualToString:#"true"] || [value isEqualToString:#"false"]) {
return 2;
}
else {
// a: Whether to accept 0
NSRange range;
NSString *expression = #"^[1-9][0-9]*$";
range = [value rangeOfString:expression options:NSRegularExpressionSearch];
if (range.location != NSNotFound) {
return 1;
} else {
if (a == YES) {
if (value.length == 1 && [value isEqualToString:#"0"]) {
return 1;
} else {
return 0;
}
}
else {
return 0;
}
}
}
}
If the string (value) is boolean, it should return 2. If it's an integer, it should return 1. Otherwise, it will return 0. That is, if it's a string, whether it's empty or not, you'll get 0. If you want to include '0' as a number, set 'a' to YES. This function is tested under the OSX platform.
You can use NSScanner, an algorithm in outline :
Create an instance of NSScanner for your text string
Based on the value of your type string call the appropriate method of NSScanner, e.g. scanInteger: for integers and scanString:intoString: for booleans (hint: scan for the boolean literals)
If the scanning method returns YES then check the isAtEnd method to make sure there is no garbage after the scanned value
HTH

Check whether an NSString contains a special character and a digit

I need to check whether a string contains one uppercase letter, one lower case letter, one integer and one special character. How do I check?
Without any additional frameworks:
NSCharacterSet * set = [[NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"] invertedSet];
if ([aString rangeOfCharacterFromSet:set].location != NSNotFound) {
NSLog(#"This string contains illegal characters.");
}
You could also use a regex (this syntax is from RegexKitLite: http://regexkit.sourceforge.net):
if ([aString isMatchedByRegex:#"[^a-zA-Z0-9]"]) {
NSLog(#"This string contains illegal characters.");
}
Found a slightly better implementation. Improvement on Ameesh's answer
- (BOOL)isValidString:(NSString *)string
{
return [string rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]].location != NSNotFound &&
[string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]].location != NSNotFound &&
[string rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound;
}
Maulik's answer is incorrect. That will check for anything OTHER than any alphanumeric character, but doesn't enforce that there be one uppercase letter, one lowercase letter, and one integer. You do in fact have to do 3 checks to verify each constraint.
NSCharacterSet *lowerCaseChars = [NSCharacterSet characterSetWithCharactersInString:#"abcdefghijklmnopqrstuvwxyz"];
NSCharacterSet *upperCaseChars = [NSCharacterSet characterSetWithCharactersInString:#"ABCDEFGHIJKLKMNOPQRSTUVWXYZ"];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:#"0123456789"];
if ([aString rangeOfCharacterFromSet:lowerCaseChars].location == NSNotFound || [aString rangeOfCharacterFromSet:upperCaseChars].location = NSNotFound || [aString rangeOfCharacterFromSet:numbers].location == NSNotFound) {
NSLog(#"This string contains illegal characters");
}
For Arabic/English
NSString *regEx = #"^([a-zA-Z0-9\u0600-\u06ff](\\-|\\_|\\.|\\ )?)+$";
NSPredicate *regExPredicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",regEx];
BOOL myStringMatchesRegEx = [regExPredicate evaluateWithObject: self.text];
if (!myStringMatchesRegEx)
return NO;
Here is what I would do. Create Regular expressions for every condition you need to check if corresponding value present or not.
i.e. Regular Expression to check if it has one uppercase letter, one lower case letter , one integer and one special character, and so on.
and then use the same string to check against every regular expression if all of them return true you have winner if not then string doesn't match to your criteria.
// Example for the Validating UpperCaseLetter do same for all others with matching regular expression.
-(BOOL) validateOneUpperCaseLetter:(NSString *)string {
if ((string == nil) || ([string isEqualToString: #""])) {
return NO;
}
// Change this regEx to one you needed. // this one validates for the "name".
NSString *regEx = #"^[a-zA-Z]+(([\\'\\,\\.\\ -][a-zA-Z])?[a-zA-Z]\\s*)*$";
NSPredicate *regExPredicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",regEx];
BOOL myStringMatchesRegEx = [regExPredicate evaluateWithObject: string];
if (!myStringMatchesRegEx) {
return NO;
}
return YES;}

String comparison in Objective-C

I've currently got a webserver set up which I communicate over SOAP with my iPhone app. I am returning a NSString containing a GUID and when I attempt to compare this with another NSString I get some strange results.
Why would this not fire? Surely the two strings are a match?
NSString *myString = #"hello world";
if (myString == #"hello world")
return;
Use the -isEqualToString: method to compare the value of two strings. Using the C == operator will simply compare the addresses of the objects.
if ([category isEqualToString:#"Some String"])
{
// Do stuff...
}
You can use case-sensitive or case-insensitive comparison, depending what you need.
Case-sensitive is like this:
if ([category isEqualToString:#"Some String"])
{
// Both strings are equal without respect to their case.
}
Case-insensitive is like this:
if ([category compare:#"Some String" options:NSCaseInsensitiveSearch] == NSOrderedSame)
{
// Both strings are equal with respect to their case.
}
You can compare string with below functions.
NSString *first = #"abc";
NSString *second = #"abc";
NSString *third = [[NSString alloc] initWithString:#"abc"];
NSLog(#"%d", (second == third))
NSLog(#"%d", (first == second));
NSLog(#"%d", [first isEqualToString:second]);
NSLog(#"%d", [first isEqualToString:third]);
Output will be :-
0
1
1
1

How to capitalize the first word of the sentence in Objective-C?

I've already found how to capitalize all words of the sentence, but not the first word only.
NSString *txt =#"hi my friends!"
[txt capitalizedString];
I don't want to change to lower case and capitalize the first char. I'd like to capitalize the first word only without change the others.
Here is another go at it:
NSString *txt = #"hi my friends!";
txt = [txt stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[txt substringToIndex:1] uppercaseString]];
For Swift language:
txt.replaceRange(txt.startIndex...txt.startIndex, with: String(txt[txt.startIndex]).capitalizedString)
The accepted answer is wrong. First, it is not correct to treat the units of NSString as "characters" in the sense that a user expects. There are surrogate pairs. There are combining sequences. Splitting those will produce incorrect results. Second, it is not necessarily the case that uppercasing the first character produces the same result as capitalizing a word containing that character. Languages can be context-sensitive.
The correct way to do this is to get the frameworks to identify words (and possibly sentences) in the locale-appropriate manner. And also to capitalize in the locale-appropriate manner.
[aMutableString enumerateSubstringsInRange:NSMakeRange(0, [aMutableString length])
options:NSStringEnumerationByWords | NSStringEnumerationLocalized
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[aMutableString replaceCharactersInRange:substringRange
withString:[substring capitalizedStringWithLocale:[NSLocale currentLocale]]];
*stop = YES;
}];
It's possible that the first word of a string is not the same as the first word of the first sentence of a string. To identify the first (or each) sentence of the string and then capitalize the first word of that (or those), then surround the above in an outer invocation of -enumerateSubstringsInRange:options:usingBlock: using NSStringEnumerationBySentences | NSStringEnumerationLocalized. In the inner invocation, pass the substringRange provided by the outer invocation as the range argument.
Use
- (NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)separator
and capitalize the first object in the array and then use
- (NSString *)componentsJoinedByString:(NSString *)separator
to join them back
pString = [pString
stringByReplacingCharactersInRange:NSMakeRange(0,1)
withString:[[pString substringToIndex:1] capitalizedString]];
you can user with regular expression i have done it's works for me simple you can paste below code
+(NSString*)CaptializeFirstCharacterOfSentence:(NSString*)sentence{
NSMutableString *firstCharacter = [sentence mutableCopy];
NSString *pattern = #"(^|\\.|\\?|\\!)\\s*(\\p{Letter})";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:NULL];
[regex enumerateMatchesInString:sentence options:0 range:NSMakeRange(0, [sentence length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
//NSLog(#"%#", result);
NSRange r = [result rangeAtIndex:2];
[firstCharacter replaceCharactersInRange:r withString:[[sentence substringWithRange:r] uppercaseString]];
}];
NSLog(#"%#", firstCharacter);
return firstCharacter;
}
//Call this method
NsString *resultSentence = [UserClass CaptializeFirstCharacterOfSentence:yourTexthere];
An alternative solution in Swift:
var str = "hello"
if count(str) > 0 {
str.splice(String(str.removeAtIndex(str.startIndex)).uppercaseString, atIndex: str.startIndex)
}
For the sake of having options, I'd suggest:
NSString *myString = [NSString stringWithFormat:#"this is a string..."];
char *tmpStr = calloc([myString length] + 1,sizeof(char));
[myString getCString:tmpStr maxLength:[myString length] + 1 encoding:NSUTF8StringEncoding];
int sIndex = 0;
/* skip non-alpha characters at beginning of string */
while (!isalpha(tmpStr[sIndex])) {
sIndex++;
}
toupper(tmpStr[sIndex]);
myString = [NSString stringWithCString:tmpStr encoding:NSUTF8StringEncoding];
I'm at work and don't have my Mac to test this on, but if I remember correctly, you couldn't use [myString cStringUsingEncoding:NSUTF8StringEncoding] because it returns a const char *.
In swift you can do it as followed by using this extension:
extension String {
func ucfirst() -> String {
return (self as NSString).stringByReplacingCharactersInRange(NSMakeRange(0, 1), withString: (self as NSString).substringToIndex(1).uppercaseString)
}
}
calling your string like this:
var ucfirstString:String = "test".ucfirst()
I know the question asks specifically for an Objective C answer, however here is a solution for Swift 2.0:
let txt = "hi my friends!"
var sentencecaseString = ""
for (index, character) in txt.characters.enumerate() {
if 0 == index {
sentencecaseString += String(character).uppercaseString
} else {
sentencecaseString.append(character)
}
}
Or as an extension:
func sentencecaseString() -> String {
var sentencecaseString = ""
for (index, character) in self.characters.enumerate() {
if 0 == index {
sentencecaseString += String(character).uppercaseString
} else {
sentencecaseString.append(character)
}
}
return sentencecaseString
}