NSString简单细说(八)—— 识别和比较字符串

版本记录

版本号时间
V1.02017.05.07

前言

前面我简单的写了些NSString的初始化,写了几篇,都不难,但是可以对新手有一定的小帮助,对于大神级人物可以略过这几篇,NSString本来就没有难的,都是细枝末节,忘记了查一下就会了,没有技术难点,下面我们继续~~~
1. NSString简单细说(一)—— NSString整体架构
2. NSString简单细说(二)—— NSString的初始化
3. NSString简单细说(三)—— NSString初始化
4. NSString简单细说(四)—— 从URL初始化
5. NSString简单细说(五)—— 向文件或者URL写入
6. NSString简单细说(六)—— 字符串的长度
7. NSString简单细说(七)—— 与C字符串的转化

详述

识别和比较字符串

一、- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;

这个用于字符串的比较,比较结果是个枚举NSComparisonResult。如下:

typedef enum NSComparisonResult : NSInteger {
    NSOrderedAscending = -1L,
    NSOrderedSame,
    NSOrderedDescending
} NSComparisonResult;
```

这里

```
NSOrderedAscending  //左边的小于右边的
        The left operand is smaller than the right operand.
NSOrderedSame  //左边的字符串等于右边的
        The two operands are equal.
NSOrderedDescending  //左边的字符串大于右边的
        The left operand is greater than the right operand.
```

下面我们直接看代码。

```

    /**
     *1.- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
     *
     *  @param string:The string with which to compare the receiver.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
    
    NSString *ocStr1 = @"AABBCC";
    NSString *ocStr2 = @"aABBCC";
    NSString *ocStr3 = @"AABCCC";
    
    NSComparisonResult result1 = [ocStr1 caseInsensitiveCompare:ocStr2];
    NSLog(@"result1--%ld",result1);

    NSComparisonResult result2 = [ocStr1 caseInsensitiveCompare:ocStr3];
    NSLog(@"result2--%ld",result2);

```

看结果。

```
2017-05-07 15:06:52.485 NSString你会用吗?[2596:103484] result1--0
2017-05-07 15:06:52.485 NSString你会用吗?[2596:103484] result2---1

```

**结论**:0代表左右相等,也就是说这个方法比较不区分大小写,-1代表上升,左边小于右边,1代表下降,左边大于右边。因为ocStr1的第四位是B,ocStr3的第四位是C,则前者小于后者,返回的是-1。需要说明的是这个方法和 compare:options:方法option 参数取值NSCaseInsensitiveSearch时是一样的。当处理的字符串是要呈现给用户时,需要使用的是localizedCaseInsensitiveCompare:方法。为什么要用这个方法?因为有些语言并不是基于英文字母的。例如: 对于汉语字符,就存在[A-Z]字母表和汉字发音之间的对应关系, 而且对于app用户而言, 汉语字符顺序'基本上'是基于发音的。'基本上'意味着并不是100%遵从这条规则。有些生僻汉字不是基于发音 (这些汉字如此生僻, 以至于你可以认为发音就是正确的排序规则)。

----------

### 二、- (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;

看代码。

```

    /**
     *2. - (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.     
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
    
    NSString *ocStr1 = @"good morning";
    NSString *ocStr2 = @"早上好";
    
    NSComparisonResult result1 = [ocStr1 localizedCaseInsensitiveCompare:ocStr2];
    NSLog(@"result1--%ld",result1);


```

看结果。

```
2017-05-07 15:50:06.849 NSString你会用吗?[3211:138318] result1---1

```

**结论**:这个要根据locale来确定,是不区分大小写的比较。

-----------


### 三、- (NSComparisonResult)compare:(NSString *)string;

看代码。

```
    /**
     *3. - (NSComparisonResult)compare:(NSString *)string;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
    
        NSString *ocStr1 = @"AABBCC";
        NSString *ocStr2 = @"aABBCC";
        NSString *ocStr3 = @"AABCCC";
    
        NSComparisonResult result1 = [ocStr1 compare:ocStr2];
        NSLog(@"result1--%ld",result1);
    
        NSComparisonResult result2 = [ocStr1 compare:ocStr3];
        NSLog(@"result2--%ld",result2);

```

看结果。

```
2017-05-07 16:02:02.135 NSString你会用吗?[3373:145514] result1---1
2017-05-07 16:02:02.136 NSString你会用吗?[3373:145514] result2---1

```

**结论**:结果是-1,都是上升的,左边小于右边,也就是说它们的比较是区分大小写的。同样,如果处理的文本是要呈现给用户时,这时候使用的应该是localizedStandardCompare: 方法。

-------------

### 四、- (NSComparisonResult)localizedCompare:(NSString *)string;

```

    /**
     *4. - (NSComparisonResult)localizedCompare:(NSString *)string;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
    
        NSString *ocStr1 = @"早上好";
        NSString *ocStr2 = @"早上好";
    
        NSComparisonResult result1 = [ocStr1 localizedCompare:ocStr2];
        NSLog(@"result1--%ld",result1);


```

看结果。

```

2017-05-07 16:15:13.405 NSString你会用吗?[3750:157885] result1--0

```

**结论**:本地化字符串的比较,同样,如果处理的文本是要呈现给用户时,这时候使用的应该是localizedStandardCompare: 方法。

----------

### 五、- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;

这里重要的就是这个option参数,如下:

```

typedef NS_OPTIONS(NSUInteger, NSStringCompareOptions) {
    //不区分大小写的比较
    NSCaseInsensitiveSearch = 1,

    //区分大小写的比较
    NSLiteralSearch = 2,        /* Exact character-by-character equivalence */

    //从字符串末尾开始搜索
    NSBackwardsSearch = 4,      /* Search from end of source string */

    //搜索限制范围的字符串
    NSAnchoredSearch = 8,       /* Search is limited to start (or end, if NSBackwardsSearch) of source string */

    //按照字符串里面的数字为依据进行比较
    NSNumericSearch = 64,       /* Added in 10.2; Numbers within strings are compared using numeric value, that is, Foo2.txt < Foo7.txt < Foo25.txt; only applies to compare methods, not find */

    //忽略"-"符号的比较
    NSDiacriticInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 128, /* If specified, ignores diacritics (o-umlaut == o) */

    //忽略字符串的长度算出比较结果
    NSWidthInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 256, /* If specified, ignores width differences ('a' == UFF41) */

    //忽略不区分大小写比较的选项,并强制返回NSOrderedAscending 或者 NSOrderedDescending
    NSForcedOrderingSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 512, /* If specified, comparisons are forced to return either NSOrderedAscending or NSOrderedDescending if the strings are equivalent but not strictly equal, for stability when sorting (e.g. "aaa" > "AAA" with NSCaseInsensitiveSearch specified) */

    只能应用于 rangeOfString:..., stringByReplacingOccurrencesOfString:...和 replaceOccurrencesOfString:... 方法。使用通用兼容的比较方法,如果设置此项,可以去掉 NSCaseInsensitiveSearch 和 NSAnchoredSearch
    NSRegularExpressionSearch NS_ENUM_AVAILABLE(10_7, 3_2) = 1024    /* Applies to rangeOfString:..., stringByReplacingOccurrencesOfString:..., and replaceOccurrencesOfString:... methods only; the search string is treated as an ICU-compatible regular expression; if set, no other options can apply except NSCaseInsensitiveSearch and NSAnchoredSearch */
};

```

下面看代码。


```
    /**
     *5. - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.
     *  @param mask:Options for the search—you can combine any of the following using a C bitwise OR operator: NSCaseInsensitiveSearch, NSLiteralSearch, NSNumericSearch. See String Programming Guide for details on these options.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
    
        //不区分大小写
        NSString *ocStr1 = @"AABBCC";
        NSString *ocStr2 = @"aABBCC";
        NSComparisonResult result1 = [ocStr1 compare:ocStr2 options:NSCaseInsensitiveSearch];
        NSLog(@"result1--%ld",result1);

        //严格区分大小写
        NSString *ocStr3 = @"AABBCC";
        NSString *ocStr4 = @"aABBCC";
        NSComparisonResult result2 = [ocStr3 compare:ocStr4 options:NSLiteralSearch];
        NSLog(@"result2--%ld",result2);
    
        //倒序比较
        NSString *ocStr5 = @"AABBCC";
        NSString *ocStr6 = @"aABBCA";
        NSComparisonResult result3 = [ocStr5 compare:ocStr6 options:NSBackwardsSearch];
        NSLog(@"result3--%ld",result3);
    
        //数字比较
        NSString *ocStr7 = @"AAB33BCC";
        NSString *ocStr8 = @"aAB44BCC";
        NSComparisonResult result4 = [ocStr7 compare:ocStr8 options:NSNumericSearch];
        NSLog(@"result4--%ld",result4);
```

下面看结果。

```
2017-05-07 16:50:09.606 NSString你会用吗?[4229:183365] result1--0
2017-05-07 16:50:09.606 NSString你会用吗?[4229:183365] result2---1
2017-05-07 16:50:09.606 NSString你会用吗?[4229:183365] result3---1
2017-05-07 16:50:09.607 NSString你会用吗?[4229:183365] result4---1

```

**结论**:如果处理的文本是要呈现给用户时,这时候使用的应该是localizedStandardCompare: 方法,或者使用compare:options:range:locale:,传入用户的locale。还有这里的mask参数,不一定是一个单一的枚举值,还可以是很多个枚举值一起使用,利用或"|"进行连接使用。

-----------

### 六、- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare;

  这个大家应该很清楚,和五中的方法相比,差的就是range这一个参数,也就是说这个方法可以比较一定区间的大小,当range的范围是整个字符串的时候,就可以看做和五方法是等价的了。下面看代码。

```
    /**
     *6. - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.
     *  @param mask:Options for the search—you can combine any of the following using a C bitwise OR operator: NSCaseInsensitiveSearch, NSLiteralSearch, NSNumericSearch. See String Programming Guide for details on these options.
     *  @param range:the range of string for comparision.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */

        //不区分大小写
        NSString *ocStr1 = @"AABBCC";
        NSString *ocStr2 = @"AABBCA";
        NSRange range1 = NSMakeRange(0, ocStr1.length);
        NSComparisonResult result1 = [ocStr1 compare:ocStr2 options:NSCaseInsensitiveSearch range:range1];
        NSLog(@"result1==%ld",result1);
    
        NSRange range2 = NSMakeRange(0, 1);
        NSComparisonResult result2 = [ocStr1 compare:ocStr2 options:NSCaseInsensitiveSearch range:range2];
        NSLog(@"result2==%ld",result2);

```

看结果。

```

2017-05-07 17:18:28.943 NSString你会用吗?[4669:202369] result1==1
2017-05-07 17:18:28.944 NSString你会用吗?[4669:202369] result2==-1

```

**结论**:如果处理的文本是要呈现给用户时,这时候使用的应该是localizedStandardCompare: 方法,或者使用compare:options:range:locale:,传入用户的locale。range也不能越界,否则会报错,NSRangeException。

--------------

### 七、- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare locale:(id)locale;

看代码。

```

    /**
     *7. - (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToCompare locale:(id)locale;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.
     *  @param mask:Options for the search—you can combine any of the following using a C bitwise OR operator: NSCaseInsensitiveSearch, NSLiteralSearch, NSNumericSearch. See String Programming Guide for details on these options.
     *  @param range:the range of string for comparision.
     *  @param locale:An instance of NSLocale. To use the current locale, pass [NSLocale currentLocale]. For example, if you are comparing strings to present to the end-user, use the current locale. To use the system locale, pass nil.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
        NSString *ocStr1 = @"AABBCC";
        NSString *ocStr2 = @"AABBCA";
        NSRange range1 = NSMakeRange(0, ocStr1.length);
        NSComparisonResult result1 = [ocStr1 compare:ocStr2 options:NSCaseInsensitiveSearch range:range1 locale:[NSLocale currentLocale]];
        NSLog(@"result1==%ld",result1);

```
看结果。

```
2017-05-07 17:26:37.468 NSString你会用吗?[4790:209130] result1==1

```
**结论**:如果处理的文本是要呈现给用户时,这时候使用的应该是localizedStandardCompare: 方法,或者使用compare:options:range:locale:,传入用户的locale。range也不能越界,否则会报错,NSRangeException。还有就是locale
这个参数,使用当地,就传[NSLocale currentLocale],使用系统的就用nil。需要注意的是locale参数影响的是相等和排序算法,例如在一些地区,重音字符要排在普通字符之后,在另外一写地区将他们排在"z"之后。

-------------

### 八、- (NSComparisonResult)localizedStandardCompare:(NSString *)string;

```
    /**
     *8. - (NSComparisonResult)localizedStandardCompare:(NSString *)string;
     *
     *  @param string:This value must not be nil. If this value is nil, the behavior is undefined and may change in future versions of macOS.
     *
     *  @return :Returns an NSComparisonResult value that indicates the lexical ordering. NSOrderedAscending the receiver precedes aString in lexical ordering, NSOrderedSame the receiver and aString are equivalent in lexical value, and NSOrderedDescending if the receiver follows aString.
     *
     */
    NSString *ocStr1 = @"AABBCC";
    NSString *ocStr2 = @"AABBCA";
    NSComparisonResult result1 = [ocStr1 localizedStandardCompare:ocStr2];
    NSLog(@"result1==%ld",result1);
```

看结果。

```

2017-05-07 17:35:37.829 NSString你会用吗?[4929:214923] result1==1

```

**结论**:利用这个方法进行排序,在不同的地区排序结果是不一样的,并且在未来发布版本的时候还可能会发生变化,这个方法的locale使用的是current locale。

-------------

### 九、-  (BOOL)hasPrefix:(NSString *)str;

看代码。

```

    /**
     *9. - (BOOL)hasPrefix:(NSString *)str;     
     *
     *  @param string:a string
     *
     *  @return :YES if aString matches the beginning characters of the receiver, otherwise NO. Returns NO if aString is empty.
     *
     */
    NSString *ocStr1 = @"AABBCC";
    
    BOOL isHasPrefix = [ocStr1 hasPrefix:@"AA"];
    NSLog(@"isHasPrefix==%d",isHasPrefix);
    
    BOOL isHasPrefix1 = [ocStr1 hasPrefix:@"AAA"];
    NSLog(@"isHasPrefix1==%d",isHasPrefix1);


```

看结果。
```
2017-05-07 17:45:08.300 NSString你会用吗?[5087:224155] isHasPrefix==1
2017-05-07 17:45:08.301 NSString你会用吗?[5087:224155] isHasPrefix1==0

```

**结论**:这里就不解释了,0就是表示不以所选择的字符串做前缀,1就表示以所选择的字符串做前缀。需要说的是,这个方法可以看做方法五中的option为 NSAnchoredSearch的特殊情况。

-------------


### 十、- (BOOL)hasSuffix:(NSString *)str;

看代码。

```
    /**
     *10. - (BOOL)hasSuffix:(NSString *)str;
     *
     *  @param string:a string
     *
     *  @return :YES if aString matches the beginning characters of the receiver, otherwise NO. Returns NO if aString is empty.
     *
     */
    NSString *ocStr1 = @"AABBCC";
    
    BOOL isHasPrefix = [ocStr1 hasSuffix:@"BCC"];
    NSLog(@"isHasPrefix==%d",isHasPrefix);
    
    BOOL isHasPrefix1 = [ocStr1 hasSuffix:@"ABCC"];
    NSLog(@"isHasPrefix1==%d",isHasPrefix1);


```

看结果。

```
2017-05-07 17:50:28.910 NSString你会用吗?[5206:228422] isHasPrefix==1
2017-05-07 17:50:28.911 NSString你会用吗?[5206:228422] isHasPrefix1==0

```

**结论**:这里就不解释了,0就是表示不以所选择的字符串做后缀,1就表示以所选择的字符串做后缀。需要说的是,这个方法可以看做方法五中的option为 NSAnchoredSearch的特殊情况。

--------------



### 十一、- (BOOL)isEqualToString:(NSString *)aString;

先看代码。

```
    /**
     *11. - (BOOL)isEqualToString:(NSString *)aString;
     *
     *  @param aString:The string with which to compare the receiver.
     *
     *  @return :YES if aString is equivalent to the receiver (if they have the same id or if they are NSOrderedSame in a literal comparison), otherwise NO.
     *
     */
    NSString *ocStr1 = @"AABBCC";
    NSString *ocStr2 = @"AABBCD";
    BOOL isEqualStr = [ocStr1 isEqualToString:ocStr2];
    NSLog(@"isEqualStr==%d",isEqualStr);
```
看结果。

```

2017-05-07 18:09:41.126 NSString你会用吗?[5444:242832] isEqualStr==0

```

**结论**:这个比较是采用标准的字符串进行比较的,也就是说用字符串的长度乘以UTF-16单位编码长度组成该字符串。当比较时,如果单个编码相同时,字符串就是相同的,比较时比较的是UTF-16编码单元。比如“Ö” 表示由“O” (U+004F LATIN CAPITAL LETTER O) 和 “¨” (U+0308 COMBINING DIAERESIS) 组成,不会与“Ö” 这个代表单个编码字符 (U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS)进行比较。而且如果你确定两个比较的对象是字符串时,该方法要优于方法isEqual:。

-------------



### 十二、@property(readonly) NSUInteger hash;

一个无符号的整形数字作为哈希表的地址,看代码。

```
    /**
     *12. @property(readonly) NSUInteger hash;
     *
     */
    
    NSString *ocStr1 = @"AABBCC";
    NSString *ocStr2 = @"AABBCC";
    NSUInteger ocStr1Hash = ocStr1.hash;
    NSUInteger ocStr2Hash = ocStr2.hash;
    NSLog(@"ocStr1Hash==%lu,ocStr2Hash==%lu",ocStr1Hash,ocStr2Hash);
    if (ocStr1Hash == ocStr2Hash) {
        NSLog(@"他俩是相等的字符串");
    }

```

看结果。

```
2017-05-07 18:22:51.766 NSString你会用吗?[5640:252521] ocStr1Hash==6494203873124370,ocStr2Hash==6494203873124370
2017-05-07 18:22:51.766 NSString你会用吗?[5640:252521] 他俩是相等的字符串
```

**结论**:相等的字符串拥有相同的hash值。


#  后记

>   两天的假期就这么结束了,这个今天就写这么多了,NSString剩下的以后写,未完,待续~~~


![秋](http://upload-images.jianshu.io/upload_images/3691932-cb5eb656d457385c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/500)



作者:刀客传奇
链接:https://www.jianshu.com/p/fb2d1c462e26
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值