用户
 找回密码
 立即注册

发帖

iOS开发的一些小贴士

[复制链接]
  • TA的每日心情
    开心
    2021-12-5 21:55
  • 208

    主题

    85

    回帖

    1万

    积分

    普通会员

    积分
    14437
    发表于 2016-4-19 14:16:34
    总是在项目中遇到比较小的问题,以前都没怎么放在心上,今天下班前在和同事讨论,怎么一段字符串中寻找相关的子字符串然后在将其替换掉,(如将链接替换成”link” “www.google.com” -> “link”)。我说我记得以前有处理过,看了自己的代码以后,笑了。。。
    & Q& |  S+ ]9 q9 f今天来说说链接的正则匹配  H3 N' t6 k6 t) ?! g
    NSRegularExpression For Link (2016-04-18)
    2 g# f* s# Z% c. g  L. b4 s! M
    1. #define TestRegularString @"\n This is the test string:1.www.google.com \n 2.http://www.google.com \n 3.https://www.google.com \n 4.Http://www.google.com.cn \n 5.ftp://www.google.com \n 6.http://127.0.0.1:16823 \n"" K9 |5 R2 e4 o$ i
    复制代码
    就像将上面宏定义的字符串里面的链接找出来 并且匹配替换成”网页链接”) \9 l0 E3 v7 n
    先上我以前处理时的代码:
    & }. ?+ F0 h( c1 f
    1. - (void)formatStringOne {9 w: a" T: G* q3 P- d) ~- g, A
    2.     NSMutableString *formatedString = [TestRegularString mutableCopy];
      ! P0 ?0 H9 M: e' v/ \0 m5 }
    3.     static NSRegularExpression *iExpression = nil;
      0 x8 f. u$ Q6 x$ c* O. Y6 X
    4.     NSError *error = nil;5 ~! k3 x5 `$ S5 \2 t* S" d
    5.     iExpression = iExpression ?: [NSRegularExpression regularExpressionWithPattern:@"((http{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)" options:0 error:&error];
      6 N, Q0 d2 {- q4 ]. I
    6.     if (error) {
      7 @; r2 t$ |& [. ]
    7.         NSLog(@"error:%@",error);
      8 A- i/ E" X* E2 ?% F6 H
    8.         return;
      * L' b4 l: P$ I- \8 q
    9.     }" J5 E. H8 H+ G7 g/ a
    10.     NSMutableArray *linkArray = [@[] mutableCopy];) ]( M7 T4 b$ B6 B" {2 b
    11.     [linkArray addObjectsFromArray:[iExpression matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)]];
      0 Z  _; y2 h, @0 D
    12.     while (linkArray.count > 0) {
      , G" Y) Z8 E* k9 B
    13.         NSTextCheckingResult *result = [linkArray firstObject];* C0 `8 Q3 Z/ \8 I
    14.         [formatedString replaceCharactersInRange:result.range withString:@"网页链接"];0 z! Y0 ~. n; s$ o
    15.    
      ! X. N  |4 h& {1 G( y6 P/ G4 A
    16.         [linkArray removeAllObjects];
      # ]% o; I/ t% g5 y6 O8 f, Z8 h
    17.         [linkArray addObjectsFromArray:[iExpression matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)]];
      , z% B% m' `4 M' G, C# I6 d
    18.     }) M8 E0 ?' C: C  L7 T
    19.     NSLog(@"%s formatedString:%@",__func__,formatedString);
      8 J6 P- ~+ |' y- T8 v" p
    20. }
    复制代码
    6 c( {$ n5 A5 V! j$ q% w5 Y
    哎哟,不知道从哪里找了段正则(正则我不是很熟悉。。。。) 功能能够实现,并且只遍历了n次,但是总感觉有点low。当时应该是知道得从第一个开始替换,后遇到了怎么获取替换后下一个位置的难题,然后就用了此方法。
    再看从so上面找到的trick method
    6 g& U$ d9 y4 i, Q) ?6 Q) Q
    1. - (void)formatStringTwo {5 w! |6 Y: |  f) t# [- m3 G
    2.     // http://stackoverflow.com/questions/11379593/use-nsregularexpression-to-replace-each-match-with-a-result-of-method" ?2 d( T$ P$ ]. b
    3.     NSError *error = nil;
      5 T8 J: F2 G8 I' A/ ]; P: ~
    4.     NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];3 A2 _+ i/ c+ _: ]" P6 u: }; J8 B
    5.     if (error) {
      + o, P" c9 q# Y+ H' ]
    6.         NSLog(@"error:%@",error);- B/ l1 ^. r* C& [' u" ~  f* [
    7.         return;
      6 [7 g& V! Z3 p, i, F
    8.     }
      & B9 [! x- M% h9 e
    9.     NSMutableString *formatedString = [TestRegularString mutableCopy];% U8 ?; }$ }+ }% v' ?6 s
    10.     NSArray *linkArray = [detector matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)];
      ) d9 }" C$ _& t+ d
    11.     for (NSTextCheckingResult *result in [linkArray reverseObjectEnumerator]) {6 \7 A6 a/ l# B* ~9 O; g! {: x, c
    12.          [formatedString replaceCharactersInRange:result.range withString:@"网页链接"];
      & w0 c4 m7 U) @
    13.     }
      ) T2 t$ Z2 L  G
    14.     NSLog(@"%s formatedString:%@",__func__,formatedString);% K" C+ c7 Z: w5 |
    15. }
    复制代码
    真的很nice,从后面开始替换,我就不用管替换前后的位置了。。。
    1 P  |1 @* m: L$ N; R! M3 e9 [再来一段利用偏移量处理的代码  Y  n% S8 e! v& h! ~1 d7 K  l
    1. - (void)formatStringThree {% Y; Q. y/ C8 p# z6 `% ?
    2.     NSError *error = nil;1 `1 o. f: c6 |, J: j. |
    3.     NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];( Y/ _7 I* A  L, Y% [" P
    4.     if (error) {
      * d& z( ?! x4 o1 Q: q3 }: ]! }
    5.         NSLog(@"error:%@",error);
      1 f! B' Q8 o) p  Y1 x
    6.         return;
      . V* u1 ~5 [: S( V+ K% m
    7.     }2 K$ y$ X) v- m! D2 x. g' O0 x
    8.     NSMutableString *formatedString = [TestRegularString mutableCopy];' }* e  N' |$ C+ f: ?
    9.     NSInteger offset = 0;
      * L6 S0 V! B0 |+ O0 ~! l
    10.     for (NSTextCheckingResult *result in [detector matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)]) {
      4 L# P9 @" S1 B' d, _) u( H1 G
    11.         NSRange resultRange = result.range;/ r7 b& g  t, n1 J# l
    12.         resultRange.location += offset;
      ! m7 i: M2 l0 Q) g  B$ [& \' ~
    13.         
      , f# n, f5 e0 x" Q4 n
    14. //        NSString *matchString = [detector replacementStringForResult:result inString:formatedString offset:offset template:@""];
      9 g/ o6 L% C+ H5 e1 L
    15.         NSString *replaceString = @"网页链接";' ]$ Z: m6 D, V& s, R. B) L
    16.         [formatedString replaceCharactersInRange:resultRange withString:replaceString];1 U/ \' E8 }! o$ B% h% k$ z3 g
    17.         offset += ([replaceString length] - resultRange.length);+ G& C6 X2 z: A5 D  u
    18.     }
      & }# a, f2 U3 N" A, v- O! p0 o
    19.    
      : Z5 l% Q+ Y4 z- G2 T' _2 x4 }
    20.     NSLog(@"%s formatedString:%@",__func__,formatedString);
      4 {' @3 U0 D; w' ^8 ~
    21. }
    复制代码
    好吧 我们再来看看它们的输出结果5 F" D$ Z' X- C& M( c
    1. 2016-04-18 23:40:39.642 RegularExpressionTest[1642:305453] -[ViewController formatStringOne] formatedString:- D& Q, |/ r, b" ?
    2. This is the test string:1.网页链接 0 u) C$ ~# }: w6 w1 H/ }1 B' V' g" p
    3. 2.网页链接 0 f* q$ U5 c( m* O1 N+ K6 j
    4. 3.网页链接
      # [; M+ c; R4 K0 g+ h4 f" F0 l* `
    5. 4.Http://网页链接
      , F/ S8 \+ |! d6 \0 D# s; J
    6. 5.网页链接 - S. Y3 S! g- ^0 Y  B5 N, \) ^
    7. 6.http://127.0.0.1:16823   f+ v* _) n# @+ ~% Z9 H. ~8 h
    8. 2016-04-18 23:40:39.666 RegularExpressionTest[1642:305453] -[ViewController formatStringTwo] formatedString:7 L3 V' j/ N, _+ l" ^
    9. This is the test string:网页链接
      3 [9 B: R+ V9 T( i# {
    10. 2.网页链接
      . S: s- O2 O2 k3 ~# B, j
    11. 3.网页链接
      5 u1 I6 p- F; E- H; b
    12. 4.网页链接
      ' c) d/ U3 ]' W9 |
    13. 5.网页链接
      : C! B8 M, c$ V: U: {4 |7 _
    14. 6.网页链接
      ! f& |0 R# Y, G
    15. 2016-04-18 23:40:39.668 RegularExpressionTest[1642:305453] -[ViewController formatStringThree] formatedString:$ ?# ^( k1 h7 D: d( N
    16. This is the test string:网页链接
      + R2 b* Y! Y; C! t' M
    17. 2.网页链接 3 }; ?2 O: }3 J% B) _. Y/ F& p
    18. 3.网页链接 0 C; o1 R: ^3 E2 {8 b
    19. 4.网页链接 * k; Y& d2 _; Q( Y
    20. 5.网页链接 $ I( @7 V! F. E, H) f) s) m
    21. 6.网页链接
    复制代码
    从上可以看出,我找的正则不是很牛逼,多看Apple Document总没错,Apple已经为了提供了一个检查数据的类 NSDataDetector,我们真没必要自己去写正则匹配,关键是还匹配错误;诶,一想到swift不是开源了,于是到NSRegularExpression.swift到全局搜索了下”link”关键字,想看看苹果的正则匹配是怎么写的,结果没有找到。。。。。。突然想到这么一句话:”知识就像内裤,看不见但是很重要”,对于我等程序猿来说,算法也是一样的。
    " B( R! H6 |2 c
    使用道具 举报 回复
    发表于 2016-7-25 00:04:34
    都有点看不懂了 !!!
    使用道具 举报 回复 支持 反对
    严禁恶意灌水!!!拒绝伸手党!!!
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    ض