导航栏: 首页 评论列表

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

默认分类 2022/05/26 14:28

转自:https://blog.csdn.net/WangErice/article/details/111352898

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

(?: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


>> 留言评论