正则表达式中的非捕获匹配

  • (?:pattern)
  • (?=pattern)
  • (?!pattern)
  • (?<=pattern)
  • (?<!pattern)

在正则表达之使用中,经常会用到捕获匹配,即使用 ()进行匹配的分组会被保存在当前的执行环境变量中,从左到右以分组的括号为标志,依次编号为1,2,…,在需要时可以直接使用 \1, \2…来进行引用.而在一些匹配场景中其实保存这些变量并没有任何的意义,这时候就需要用到非捕获匹配.


(?:pattern)


(?"pattern)表示一个非捕获分组,和捕获分组比起来,非捕获分组只会进行单纯的模式匹配并不会将匹配到的值进行保存.例如,Windows(?:95|98|NT|2000)可以匹配Windows95,Windows98, WindowsNT,Windows2000,而不匹配WindowsXP:

    NSString *str = @"Windows95 Windows98 WindowsNT Windows2000 WindowsXP";
    NSError *error = nil;
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:@"Windows(?:95|98|NT|2000)" options:(0) error:&error];
    
    if (!error) {
        NSArray <NSTextCheckingResult *> * result = [reg matchesInString:str options:(0) range:(NSRange){0, str.length}];
        for (NSTextCheckingResult *ele in result) {
            NSLog(@"element ---> %@", [str substringWithRange:ele.range]);
        }
    } else {
        NSLog(@"error --> %@", error);
    }



输出结果:

 element ---> Windows95
 element ---> Windows98
 element ---> WindowsNT
 element ---> Windows2000

第一个分组中的(?:[:alpha:]+)只用于模式匹配,而第二个分组(\w+)被保存在第一个变量$1中.
(?:pattern)在使用使用 或来组合匹配模式时非常有用.例如: 'industr(?:y|ies)'就是一个比’industry|industries‘更加简略的表达式,比使用industr(y|ies)更加节约内存空间,毕竟单独保存’y’或者’ies’没有任何意义。

(?=pattern)


这种模式被称为正向肯定预查(look ahead positive assert),可以用来匹配pattern前的位置。同样这也是一个非捕获匹配,该匹配不保存匹配到的结果.
这个模式可以理解为,捕获以模式pattern结尾的指定内容.例如,Windows(?=XP)只能匹配WindowsXP中的Windows:

    NSString *str = @"Windows95 Windows98 WindowsNT Windows2000 WindowsXP";
    NSError *error = nil;
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:@"Windows(?=XP)" options:(0) error:&error];
    
    if (!error) {
        NSArray <NSTextCheckingResult *> * result = [reg matchesInString:str options:(0) range:(NSRange){0, str.length}];
        for (NSTextCheckingResult *ele in result) {
            NSLog(@"element ---> %@", [str substringWithRange:ele.range]);
        }
    } else {
        NSLog(@"error --> %@", error);
    }


输出结果为:

element ---> Windows


(?!pattern)


这个模式别称为正向否定预查(look ahead negative assert),在任何不匹配pattern的字符串处开始匹配查找字符串。同样,这也是一个非捕获匹配,该匹配结果不能给后续的环境使用.例如,Windows(?!XP)不匹配WindowsXP中的Windows,可以匹配Windows95 Windows98 WindowsNT Windows2000中的Windows:

    NSString *str = @"Windows95 Windows98 WindowsNT Windows2000 WindowsXP";
    NSError *error = nil;
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:@"Windows(?!XP)" options:(0) error:&error];
    
    if (!error) {
        NSArray <NSTextCheckingResult *> * result = [reg matchesInString:str options:(0) range:(NSRange){0, str.length}];
        for (NSTextCheckingResult *ele in result) {
            NSLog(@"element ---> %@", [str substringWithRange:ele.range]);
        }
    } else {
        NSLog(@"error --> %@", error);
    }


输出结果:

 element ---> Windows
 element ---> Windows
 element ---> Windows
 element ---> Windows

(?<=pattern)


反向(look behind)肯定预查,与正向肯定预查相反,捕获以指定模式pattern开头的内容.例如捕获所有的Windows系统名称:   

NSString *str = @"Windows95 Windows98 WindowsNT Windows2000 WindowsXP Debian Ubuntu Mint";
    NSError *error = nil;
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:@"(?<=Windows)(?:95|98|NT|2000|XP)" options:(0) error:&error];
    if (!error) {
        NSArray <NSTextCheckingResult *> * result = [reg matchesInString:str options:(0) range:(NSRange){0, str.length}];
        for (NSTextCheckingResult *ele in result) {
            NSLog(@"element ---> %@", [str substringWithRange:ele.range]);
        }
    } else {
        NSLog(@"error --> %@", error);
    }


输出结果:

 element ---> 95
 element ---> 98
 element ---> NT
 element ---> 2000
 element ---> XP
 

(?<!pattern)


反向否定预查,与正向否定预查相反,匹配不以pattern开头的内容.例如,(?<!95|98|NT|2000)Windows不能匹配95Windows 98Windows NTWindows 2000Windows中的Windows,却能匹配2009Windows中的Windows

  NSString *str = @"95Windows 98Windows NTWindows 2000Windows 2009Windows";
    NSError *error = nil;
    NSRegularExpression *reg = [NSRegularExpression regularExpressionWithPattern:@"(?<!95|98|NT|2000)Windows" options:(0) error:&error];
    if (!error) {
        NSArray <NSTextCheckingResult *> * result = [reg matchesInString:str options:(0) range:(NSRange){0, str.length}];
        for (NSTextCheckingResult *ele in result) {
            NSLog(@"element ---> %@", [str substringWithRange:ele.range]);
        }
    } else {
        NSLog(@"error --> %@", error);
    }


输出内容:

element ---> Windows


 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐