用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

发帖

iOS开发的一些小贴士

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

    主题

    293

    帖子

    1万

    积分

    超级版主

    Rank: 8Rank: 8

    积分
    14437
    发表于 2016-4-19 14:16:34
    总是在项目中遇到比较小的问题,以前都没怎么放在心上,今天下班前在和同事讨论,怎么一段字符串中寻找相关的子字符串然后在将其替换掉,(如将链接替换成”link” “www.google.com” -> “link”)。我说我记得以前有处理过,看了自己的代码以后,笑了。。。
    5 ^1 u3 O7 ]" ~& o今天来说说链接的正则匹配3 T# C4 A- c$ O0 w+ c7 _
    NSRegularExpression For Link (2016-04-18)1 T% X" f3 T, `  t
    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"1 C* M8 A! Y) g0 ]+ V0 M
    复制代码
    就像将上面宏定义的字符串里面的链接找出来 并且匹配替换成”网页链接”6 a( V& U) N; H: E) o/ C& [
    先上我以前处理时的代码:
    " |) n. S6 f3 t* R! K- M  C" F
    1. - (void)formatStringOne {
      5 H: o3 }, K% c( r& Q
    2.     NSMutableString *formatedString = [TestRegularString mutableCopy];6 C+ X% e" m& c! x
    3.     static NSRegularExpression *iExpression = nil;! S) m( ^/ _$ `4 H7 }& y
    4.     NSError *error = nil;
      + Z% C! |  C1 d8 j$ W3 E
    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];8 `9 i; k+ X2 E: y9 j
    6.     if (error) {
      3 i* F- W4 {1 G; ~' L2 Y; @/ C) L( u
    7.         NSLog(@"error:%@",error);+ Z( K4 e+ j7 K7 d0 H
    8.         return;( F  e8 F! M: p/ t& M  g
    9.     }" e+ |, o8 L" H
    10.     NSMutableArray *linkArray = [@[] mutableCopy];- p9 x+ F2 K0 ]7 s) A' L+ r
    11.     [linkArray addObjectsFromArray:[iExpression matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)]];+ z2 ~: @, Q' @
    12.     while (linkArray.count > 0) {1 _5 P7 `, K  ?  @2 `7 D
    13.         NSTextCheckingResult *result = [linkArray firstObject];; \2 ^: U' \9 U& ^9 Y4 u
    14.         [formatedString replaceCharactersInRange:result.range withString:@"网页链接"];
      3 c  l! K% N1 R
    15.    
      / H, M* w8 o; [& {8 v
    16.         [linkArray removeAllObjects];1 \" B* M# H/ H8 S. p* M
    17.         [linkArray addObjectsFromArray:[iExpression matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)]];
      " e. C) f0 W' X* d- E4 ]' c" i- x
    18.     }# W' p8 c+ C) d& V
    19.     NSLog(@"%s formatedString:%@",__func__,formatedString);3 `0 m% f# K  u, J# a
    20. }
    复制代码
    ; Q1 \% O! U0 U' g2 O) d# i* [
    哎哟,不知道从哪里找了段正则(正则我不是很熟悉。。。。) 功能能够实现,并且只遍历了n次,但是总感觉有点low。当时应该是知道得从第一个开始替换,后遇到了怎么获取替换后下一个位置的难题,然后就用了此方法。
    再看从so上面找到的trick method, s* m; j! n" M  ^! ]7 O
    1. - (void)formatStringTwo {! _) P: n$ f* K7 j* ^  _: e! P7 l1 D
    2.     // http://stackoverflow.com/questions/11379593/use-nsregularexpression-to-replace-each-match-with-a-result-of-method% G7 `2 N6 W7 r+ W% @7 w* [4 r
    3.     NSError *error = nil;
      / [$ N# q5 D) M
    4.     NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];
      2 E% G4 A# f  V5 F& U
    5.     if (error) {
      & J; h5 v: p" O. [7 G4 |
    6.         NSLog(@"error:%@",error);3 Y0 i" b) {- |; P1 R: d. s+ w
    7.         return;# R. {! Y0 m4 k/ ?# P
    8.     }+ \9 u: w1 P: Z! ^, `8 ^
    9.     NSMutableString *formatedString = [TestRegularString mutableCopy];
      7 b5 `1 N; P% U2 J( K0 i  F
    10.     NSArray *linkArray = [detector matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)];- j6 [  j$ B3 |2 \+ P- @5 F' E
    11.     for (NSTextCheckingResult *result in [linkArray reverseObjectEnumerator]) {% c+ w5 W0 |$ b) }
    12.          [formatedString replaceCharactersInRange:result.range withString:@"网页链接"];
      3 z8 h, [' G, h- ^# r$ D. Q
    13.     }. c. H& d1 i* }. b2 g6 Z
    14.     NSLog(@"%s formatedString:%@",__func__,formatedString);9 G# h# U9 Q, m7 h" Y
    15. }
    复制代码
    真的很nice,从后面开始替换,我就不用管替换前后的位置了。。。8 O/ ~- T! D* p% F2 ~' Y
    再来一段利用偏移量处理的代码
    % j& @1 v, q: J7 ]( W
    1. - (void)formatStringThree {
      5 S1 ?+ J# k, Y1 n: }# G
    2.     NSError *error = nil;6 Y) h/ n2 a& M. v
    3.     NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeLink error:&error];9 j: C4 z+ M, B0 ]8 u9 a9 Q0 z
    4.     if (error) {  [5 w: E: P- X, v
    5.         NSLog(@"error:%@",error);
      6 r7 F+ e4 H" n0 D: O7 u4 B4 k; A
    6.         return;1 h. V! \- _5 n9 D3 k+ S
    7.     }: k& A. @! S) L- y1 K  `
    8.     NSMutableString *formatedString = [TestRegularString mutableCopy];
      ) g0 v: `" a1 j
    9.     NSInteger offset = 0;
      9 L7 \& k  Y4 d# ?8 N% |, p
    10.     for (NSTextCheckingResult *result in [detector matchesInString:formatedString options:0 range:NSMakeRange(0,formatedString.length)]) {
      4 Y+ D( G9 x3 l1 w: ?
    11.         NSRange resultRange = result.range;3 P+ v) J) k' d" S6 K' q; h  y2 K
    12.         resultRange.location += offset;8 C# G9 G) {. j) M6 [% x: x( \
    13.         " x, S' t2 S( _- H3 ^. M# L
    14. //        NSString *matchString = [detector replacementStringForResult:result inString:formatedString offset:offset template:@""];
      / S$ E, m! a! P# {
    15.         NSString *replaceString = @"网页链接";) N* w8 {4 ^' j
    16.         [formatedString replaceCharactersInRange:resultRange withString:replaceString];
      4 b) X' R$ C: u! a: i! Y4 a/ U
    17.         offset += ([replaceString length] - resultRange.length);1 Z, A* M/ g5 F9 ?/ t
    18.     }
      % a3 u9 s+ W) X2 O
    19.     . L8 s) h/ P9 x9 b( b
    20.     NSLog(@"%s formatedString:%@",__func__,formatedString);+ a5 u2 H0 _# U' H3 j
    21. }
    复制代码
    好吧 我们再来看看它们的输出结果
    ) s3 u) {9 Y- G6 l; r- z2 f
    1. 2016-04-18 23:40:39.642 RegularExpressionTest[1642:305453] -[ViewController formatStringOne] formatedString:
      . N; R! ~+ c. {: i: V6 D
    2. This is the test string:1.网页链接 " ~: s# H8 j0 s" J4 T% `
    3. 2.网页链接 ! v0 n& v/ d4 B- `
    4. 3.网页链接 0 V; E5 i/ b+ C. d: G
    5. 4.Http://网页链接
      5 e2 m( N% K" @- C# ?) B6 {
    6. 5.网页链接
      7 C/ ]5 w) |4 ]2 q$ ]
    7. 6.http://127.0.0.1:16823
      $ j1 }- Q8 T# n
    8. 2016-04-18 23:40:39.666 RegularExpressionTest[1642:305453] -[ViewController formatStringTwo] formatedString:
      & ?" H7 i! w) W- n" {
    9. This is the test string:网页链接
      $ n5 v! {9 {$ R1 \/ c7 }; F- n
    10. 2.网页链接
      ! K2 c) u: N9 M  x  k
    11. 3.网页链接
      1 p. B/ S4 ^( A; N
    12. 4.网页链接 * g9 {& n0 f* |: J- Y( }( |
    13. 5.网页链接 " k' E3 ~0 \8 w9 I
    14. 6.网页链接
      0 x/ s* {1 E7 _( Z0 t3 ?
    15. 2016-04-18 23:40:39.668 RegularExpressionTest[1642:305453] -[ViewController formatStringThree] formatedString:! Z! j, ~0 W9 J6 r! \5 Q
    16. This is the test string:网页链接 9 ^, }9 ~, t* \& `
    17. 2.网页链接 % a8 i( E& N. Y% R' z, q3 `
    18. 3.网页链接 ) Z4 M- R+ V! k' Y. w* r
    19. 4.网页链接   ~( V- p+ z( C1 r! H* [
    20. 5.网页链接
      + h2 ?& Z8 u7 P( @$ t4 |1 i
    21. 6.网页链接
    复制代码
    从上可以看出,我找的正则不是很牛逼,多看Apple Document总没错,Apple已经为了提供了一个检查数据的类 NSDataDetector,我们真没必要自己去写正则匹配,关键是还匹配错误;诶,一想到swift不是开源了,于是到NSRegularExpression.swift到全局搜索了下”link”关键字,想看看苹果的正则匹配是怎么写的,结果没有找到。。。。。。突然想到这么一句话:”知识就像内裤,看不见但是很重要”,对于我等程序猿来说,算法也是一样的。
    ) L" c7 u0 H  x0 m) p' ^
    使用道具 举报 回复
    发表于 2016-7-25 00:04:34
    都有点看不懂了 !!!
    使用道具 举报 回复 支持 反对
    严禁恶意灌水!!!拒绝伸手党!!!
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    ض