iOS 獲取所有子字符串Rang


現在APP開發對效果要求越來與豐富,各種特效層出不窮。其中以動畫效果和文字以富文本展示居多。

在網上也看了好幾種方法,感覺有的處理的麻煩了,下面是我總結的獲取子字符串所有Rang的一些方法:

字符串做富文本處理需要通過NSMutableAttributedString來處理,先創建一個NSMutableAttributedString對象:

NSMutableAttributedString *attribtStr = [[NSMutableAttributedString alloc] initWithString:@"父字符串"];

1、使用NSRegularExpression來處理

//初始化NSRegularExpression  
NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:@"你的正則表達式" options:0 error:nil]; //遍歷字符串,usingBlock中返回子字符串的狀態,在usingBlock中處理子字符串
[regularExpression enumerateMatchesInString:attribtStr.
string options:0 range:NSMakeRange(0, attribtStr.string.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { //給子字符串添加雙刪除線 [attribtStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleDouble] range:result.range]; //刪除線設置為紅色 [attribtStr addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:result.range]; }];

上面方法是直接在遍歷中處理匹配的子字符串,下面的是先得到所有子字符串的狀態集,再做對應處理:

NSArray *regularExpressionArr = [regularExpression matchesInString:attribtStr.string options:0 range:NSMakeRange(0, attribtStr.string.length)];

得到子字符串的數組集合,需要做什么處理,通過循環判斷就可以完成了。

for (NSTextCheckingResult *result in regularExpressionArr) {
        NSRange rang = [result range];
        NSLog(@"%lu",rang.location);
        
        [attribtStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleDouble] range:result.range];
        [attribtStr addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:result.range];
    }

NSRegularExpression的下面幾個方法在其他情況下也是很好用的:

//獲取子字符串數目
- (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range; //獲取第一個子字符串的NSTextCheckingResult
- (nullable NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range; //獲取指定rang內第一個符合要求的子字符串
- (NSRange)rangeOfFirstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;

2.通過遞歸獲得所有子字符串的rang數組(遞歸的優缺點就不在扯了,慎用)

//通過遞歸獲取所有子字符串location
- (void)rangeOfString:(NSString*)searchString fatherString:(NSString*)fatherStr options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch {
//獲取指定范圍內第一個匹配的子字符串rang,和上面NSRegularExpression的一個方法效果一樣
NSRange rang
= [fatherStr rangeOfString:searchString options:mask range:rangeOfReceiverToSearch];
//判斷搜尋范圍來決定是否完成搜尋
if (rang.location >fatherStr.length - searchString.length) { return; }
//NSRang不能存儲在數組中,所以這里存的是rang的location [strLocationRangArr addObject:[NSNumber numberWithInteger:rang.location]];
//遞歸搜尋 [self rangeOfString:searchString fatherString:fatherStr options:mask range:NSMakeRange(rang.location
+searchString.length, fatherStr.length-rang.location-searchString.length)]; }

調用示例:

strLocationRangArr = [NSMutableArray array];
    [self rangeOfString:@"CoreText" fatherString:attribtStr.string options:0 range:NSMakeRange(0, attribtStr.string.length)];
    for (NSNumber *location in strLocationRangArr) {
        [attribtStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleDouble] range:NSMakeRange([location integerValue], 8)];
        [attribtStr addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:NSMakeRange([location integerValue], 8)];
    }

3.通過字符串- (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;方法獲得的切割數組處理獲得子字符串rang集合。

 NSArray *arr = [attribtStr.string componentsSeparatedByString:@"searchString"];

通過數組的子字符串去匹配attribtStr.string獲取searchString的location,

這種方法需要處理的地方比較多,首先要考慮arr中第一個、最后一個和連續的是否是@“”,在着就是數組中不可避免會出現相同切割為相同的子串。

例如:@“123654789123654789”這樣要search@“654”就會出現兩個@“123”和@“789”,在判斷的時候要在此處處理重復問題,小的表示有了上面兩種方法就沒有在對這種想法再做深入的實現。

相對NSRegularExpression的簡單快速的,其他方法用來作為思路還是不錯的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM