美文网首页
NSRegularExpression学习笔记

NSRegularExpression学习笔记

作者: 寻心_0a46 | 来源:发表于2020-06-06 17:23 被阅读0次

    正则表达式

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

    构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

    正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

    正则表达式普通字符

    普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。

    正则表达式非打印字符

    非打印字符也可以是正则表达式的组成部分。非打印字符的转义序列如表:

    字符 描述
    \cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
    \f 匹配一个换页符。等价于 \x0c 和 \cL。
    \n 匹配一个换行符。等价于 \x0a 和 \cJ。
    \r 匹配一个回车符。等价于 \x0d 和 \cM。
    \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
    \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
    \t 匹配一个制表符。等价于 \x09 和 \cI。
    \v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
    \d 匹配一个数字字符。等价于 [0-9]。
    \D 匹配一个非数字字符。等价于 [^0-9]。
    \w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
    \W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

    正则表达式特殊字符(元字符)

    所谓特殊字符,就是一些有特殊含义的字符,例如 runoob 中的 * 符号,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 符号进行转义,即在其前加一个 \符号。例如: runo*ob 是匹配 runoob的。

    许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符:

    特殊字符 描述
    $ 匹配输入字符串的结尾位置。要匹配 $ 字符本身,请使用 "\$"。
    ( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 " \( " 和 " \) "。
    * 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用" \* "。例如 : "ab*":表示一个字符串有一个a后面跟着零个或若干个b("a", "ab", "abbb",……)。
    + 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 " \+ "。例如 :"ab+":表示一个字符串有一个a后面跟着至少一个b或者更多( "ab", "abbb",……)。
    . 匹配除换行符" \n "之外的任何单字符。要匹配" . " ,请使用" \. "。
    [ ] 表示在括号内的众多字符中,选择1-N个括号内的符合语法的字符作为结果。例如 :"[ab]":表示一个字符串有一个"a"或"b"(相当于"a|b");"[a-d]":表示一个字符串包含小写的"a"到"d"中的一个(相当于"a|b|c|d"或者"[abcd]");"^[a-zA-Z]":表示一个以字母开头的字符串。
    ? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配" ? " 字符,请使用" \? "。例如 : "ab?":表示一个字符串有一个a后面跟着零个或者一个b( "a", "ab");
    \ 将下一个字符标记为特殊字符、或原义字符、或向后引用、或八进制转义符。例如, " n " 匹配字符 " n "。 " \n' "则匹配换行符。序列 ' \\ ' 匹配 " \ ",而 " \( " 则匹配 " ( "。
    ^ 匹配输入字符串的开始位置,但当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配" ^ "字符本身,请使用"\^ "。
    { 标记限定符表达式的开始。要匹配" { ",请使用 " \{ "。
    | 指明两项之间的一个选择。要匹配" | ",请使用" \| "。

    正则表达式限定符

    限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有" * "或" + "或" ? "或" {n} "或" {n,} "或" {n,m} "共6种。限定符出现在范围表达式之后。因此,它应用于整个范围表达式。下表列出了正则表达式中的限定符:

    字符 描述
    * 匹配前面的子表达式零次或多次。例如," zo* "能匹配 " z " 以及 " zoo "。* 等价于{0,}。
    + 匹配前面的子表达式一次或多次。例如," zo+ " 能匹配 " zo " 以及 " zoo ",但不能匹配 " z "。 等价于 {1,}。
    ? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。匹配前面的子表达式零次或一次。例如," do(es)? " 可以匹配 " do " 、 " does " 中的 " does " 、 " doxy " 中的 " do " 。等价于 {0,1}。
    {n} n 是一个非负整数。匹配确定的 n 次。例如," o{2} " 不能匹配 " Bob " 中的 " o ",但是能匹配 "food" 中的两个 " o "。
    {n,} n 是一个非负整数。至少匹配n 次。例如," o{2,} " 不能匹配 " Bob " 中的 " o ",但能匹配 " foooood " 中的所有 " o "。" o{1,} " 等价于 " o+ "。" o{0,} "则等价于 " o* "。
    {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如," o{1,3} " 将匹配 " fooooood " 中的前三个 " o "。" o{0,1} " 等价于 " o? "。请注意在逗号和两个数之间不能有空格。

    注:*、+ 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。

    正则表达式定位符

    定位符能够将正则表达式固定到行首或行尾。它们还能够创建例如出现在一个单词内、在一个单词的开头或者一个单词的结尾这样的正则表达式。定位符用来描述字符串或单词的边界,^ 和 $ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。下表列出了正则表达式中的定位符:

    字符 描述
    ^ 匹配输入字符串开始的位置。
    $ 匹配输入字符串结尾的位置。
    \b 匹配一个单词边界,即字与空格间的位置。\b 字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项。如果它位于字符串的结尾,它在单词的结尾处查找匹配项。
    \B 非单词边界匹配。

    注:不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。

    NSRegularExpression

    应用于Unicode字符串的已编译正则表达式的不可变表示形式。

    NSRegularExpression的基本匹配方法是块迭代器方法,它允许客户端提供一个块对象,每当正则表达式与目标字符串的一部分匹配时,都将调用该对象。还有其他方便的方法可以将所有匹配项作为数组返回,包括匹配项的总数、第一个匹配项和第一个匹配项的范围。

    单个匹配由NSTextCheckingResult类的一个实例表示,该实例携带有关整个匹配范围(通过其range属性)和每个单独捕获组的范围(通过rangeAtIndex:方法)的信息。对于基本的NSRegularExpression对象,这些匹配结果的类型为NSTextCheckingTypeRegularExpression,但子类可以使用其他类型。

    NSRegularExpression初始化函数

    - (nullable instancetype)initWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options error:(NSError **)error NS_DESIGNATED_INITIALIZER;
    

    函数描述 : 使用指定的正则表达式模式和选项返回已初始化的NSRegularExpression实例。

    参数 :

    pattern : 要编译的正则表达式模式。

    options : 匹配期间应用于表达式的正则表达式选项。

    error : 返回初始化过程中遇到的任何错误的输出值。如果正则表达式模式无效,则返回NSError对象;否则返回nil。

    返回值 : 指定正则表达式和选项的NSRegularExpression实例。

    NSRegularExpression (NSMatching) - 匹配项函数

    - (NSArray<NSTextCheckingResult *> *)matchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
    

    函数描述 : 返回一个数组,该数组包含字符串中正则表达式的所有匹配项。这是一个方便的方法,它调用enumerateMatchesInString:options:range:usingBlock:传递适当的字符串、选项和范围。

    参数 :

    string : 要搜索的字符串。

    options : 要使用的匹配选项。

    range : 要搜索的字符串的范围。

    返回值 : NSTextCheckingResult对象的数组。每个结果通过其range属性给出整个匹配的范围,并通过其rangeAtIndex:方法给出每个捕获组的范围。如果某个捕获组没有参与此特定匹配,则返回范围{NSNotFound, 0}。

    \color{red}{例如 :}

    NSString *regularStr = @"^/integralmall(?:\\.html){0,1}(?:\\?id=(\\d+)){0,1}(?:\\?cls_id=(\\d+)){0,1}";
    NSString *urlStr = @"/integralmall?cls_id=72$";
        
    NSError *error = nil;
    NSRegularExpression *expression = [[NSRegularExpression alloc] initWithPattern:regularStr options:0 error:&error];
        
    if(!error && [expression matchesInString:urlStr options:0 range:NSMakeRange(0, urlStr.length)].count > 0) {
        NSLog(@"匹配了路径");
    }else{
        NSLog(@"没有匹配路径");
    }
    

    NSRegularExpression (NSReplacement) - 替换函数

    - (NSString *)stringByReplacingMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range withTemplate:(NSString *)templ;
    

    函数描述 : 返回一个新的字符串,其中包含被模板字符串替换的匹配正则表达式那部分的字符串。

    参数 :

    string : 要在其中搜索值的字符串。

    options:要使用的匹配选项。

    range:要搜索的字符串的范围。

    template:替换匹配实例时使用的替换模板。

    返回值:模板字符串替换了匹配正则表达式的字符串后的新字符串。

    \color{red}{例如,去掉字符串中的HTML标签 :}

    - (void)viewDidLoad {
        
        [super viewDidLoad];
        self.navigationItem.title = @"测试代码控制器";
        NSString *newString = [self removeHtmlWithString:@"<a href=https://music.163.com/#/song?id=4900975>城南花已开</a>"];
        NSLog(@"%@",newString);
    }
    
    //正则去除标签
    -(NSString *)removeHtmlWithString:(NSString *)htmlString{
        NSRegularExpression * regularExpretion = [NSRegularExpression regularExpressionWithPattern:@"<[^>]*>|\n" options:0 error:nil];
        htmlString = [regularExpretion stringByReplacingMatchesInString:htmlString options:NSMatchingReportProgress range:NSMakeRange(0, htmlString.length) withTemplate:@""];
        return htmlString;
    }
    

    输出的结果:

    截屏2020-07-17下午3.59.28.png

    \color{red}{但有时在处理URL时,也会进行获取参数的操作,例如:}

    - (void)viewDidLoad {
        
        [super viewDidLoad];
        self.navigationItem.title = @"测试代码控制器";
        
        NSString *url = @"http://m.dm.iywdf.com/goods-2052.html?user_id=5";
        
        NSString *goodsPattern = @"^(?:https://|http://){0,1}(?:www\\.|m\\.|mkt\\.){0,1}dm.iywdf.com/goods\\-(\\d+)\\.html\\?user_id=(\\d+)";
        
        NSRegularExpression *goodsExpression = [[NSRegularExpression alloc]initWithPattern:goodsPattern options:NSRegularExpressionCaseInsensitive error:nil];
        
        if([goodsExpression matchesInString:url options:0 range:NSMakeRange(0, url.length)].count > 0){
            
            NSString*goodsId = [goodsExpression stringByReplacingMatchesInString:url options:0 range:NSMakeRange(0, url.length) withTemplate:@"$1"];
            NSString*userId = [goodsExpression stringByReplacingMatchesInString:url options:0 range:NSMakeRange(0, url.length) withTemplate:@"$2"];
            
            NSLog(@"%@",goodsId);
            NSLog(@"%@",userId);
        }
    }
    

    输出如下:

    截屏2020-07-17下午4.42.21.png

    但通过这个方法获取值,有一些值得注意的地方,例如当修改了user_id的匹配规则后:

    NSString *goodsPattern = @"^(?:https://|http://){0,1}(?:www\\.|m\\.|mkt\\.){0,1}dm.iywdf.com/goods\\-(\\d+)\\.html(\\?user_id=(\\d+)){0,1}";
    

    输出则变为如下:

    截屏2020-07-17下午5.14.22.png

    而路径中加入了?car_id=100,但是没有增加新的匹配项,例如:

    NSString *url = @"http://m.dm.iywdf.com/goods-2052.html?user_id=5?car_id=100";
    

    输出则变为如下:

    截屏2020-07-17下午5.17.59.png

    而$0则会将整条路径全部拿到,至于这些$1、$2怎样对应对应的值的问题,暂时还没有想通。

    相关文章

      网友评论

          本文标题:NSRegularExpression学习笔记

          本文链接:https://www.haomeiwen.com/subject/ntdpyhtx.html