Mani
Mani

Reputation: 17585

NSString hasPrefix: function with case sensitivity

Simple and may asked many time but little trick with this. We know, NSString doesn't work with case sensitivity for hasPrefix: method.

NSString *string = @"Xyzabcdedfghij";
    NSString *substring = @"xyz";
    if ([string hasPrefix:substring])
        NSLog(@"string has prefix "); // won't get here.

Question is: Is there any built-in method for resolve this issue? I mean, hasPrefix: with case sensitive?

I could use below answer at least case. But want to know if there is any method which better than this..?

Known answer:(lease case)

if ([[test substringWithRange:NSMakeRange(0,3)] caseInsensitiveCompare:@"xyz"] == NSOrderedSame) {
     // ....
}

Upvotes: 9

Views: 9779

Answers (8)

Hassan Taleb
Hassan Taleb

Reputation: 2526

Swift 5

extension StringProtocol {
    public func hasPrefix<T: StringProtocol>(caseInsensitive prefix: T) -> Bool {
        lowercased().starts(with: prefix.lowercased())
    }
}

Use:

"Hello World".hasPrefix(caseInsensitive: "hello") //true

Upvotes: 0

Alaeddine
Alaeddine

Reputation: 6212

Swift 5:

extension String {
    public func hasPrefixIgnoringCase(_ prefix: String) -> Bool {
        range(of: prefix, options: [.anchored, .caseInsensitive]) != nil
    }
}

Usage:

"Hello".hasPrefixIgnoringCase("hEl") // return true

Upvotes: 6

mojuba
mojuba

Reputation: 12227

For those of you who like functional style one-liners (like I do):

extension String {

    func hasPrefix<Prefix>(_ prefix: Prefix, caseSensitive: Bool) -> Bool where Prefix: StringProtocol {
        return caseSensitive ? hasPrefix(prefix) :
            self.range(of: prefix, options: [.anchored, .caseInsensitive]) != nil
    }

}

Upvotes: 0

Ben
Ben

Reputation: 1434

A Swift 4.2 version of accepted answer:

extension String {

    public func hasPrefix<Prefix>(_ prefix: Prefix, caseSensitive: Bool) -> Bool where Prefix : StringProtocol {

        if caseSensitive { return self.hasPrefix(prefix) }

        let prefixRange = self.range(of: prefix, options: [.anchored, .caseInsensitive])
        return prefixRange != nil
    }
}

Alternatively, using .lowercased()

extension String {

    public func hasPrefix<Prefix>(_ prefix: Prefix, caseSensitive: Bool) -> Bool where Prefix : StringProtocol {

        if caseSensitive { return self.hasPrefix(prefix) }
        return self.lowercased().hasPrefix(prefix.lowercased())
    }
}

The extension is to use as following

let string = "Hello World"

let caseSensitiveSearch = string.hasPrefix("hello", caseSensitive: true) // return false
let caseNotSensitiveSearch = string.hasPrefix("hello", caseSensitive: false) // return true

Upvotes: 3

trojanfoe
trojanfoe

Reputation: 122391

From Apple themselves:

NSString *searchString = @"age";

NSString *beginsTest = @"Agencies";
NSRange prefixRange = [beginsTest rangeOfString:searchString
    options:(NSAnchoredSearch | NSCaseInsensitiveSearch)];

// prefixRange = {0, 3}

NSString *endsTest = @"BRICOLAGE";
NSRange suffixRange = [endsTest rangeOfString:searchString
    options:(NSAnchoredSearch | NSCaseInsensitiveSearch | NSBackwardsSearch)];

// suffixRange = {6, 3}

This could be wrapped into an easy-to-use method:

- (BOOL) string:(NSString *)string
      hasPrefix:(NSString *)prefix
caseInsensitive:(BOOL)caseInsensitive {

    if (!caseInsensitive)
        return [string hasPrefix:prefix];

    const NSStringCompareOptions options = NSAnchoredSearch|NSCaseInsensitiveSearch;
    NSRange prefixRange = [string rangeOfString:prefix
                                        options:options];
    return prefixRange.location == 0 && prefixRange.length > 0;
}

Upvotes: 33

Janak Nirmal
Janak Nirmal

Reputation: 22726

Nasty way to do is to lower case the both string and than use hasPrefix e.g.

[[mainString lowercaseString] hasPrefix:[stringToFind lowercaseString]];

Upvotes: 9

Sumit Mundra
Sumit Mundra

Reputation: 3901

you can do this by

if([[string lowercaseString] hasPrefix:[substring lowercaseString]])
{
NSLog(@"found");
}

Upvotes: 4

Volker
Volker

Reputation: 4660

You can always use lowercaseString on both strings and thus forcing the same case. So for example

[[string lowercaseString] hasPrefix:[substring lowercaseString]];

Upvotes: 29

Related Questions