ios - NSRegularExpression : Proper regex for parsing d=4, b=5,o=63?

标签 ios regex

我正在尝试找到一个正则表达式来解析以下内容:

d=4,b=5,o=63

这样我就可以得到字母和数字了。每个字母都有一个允许的数字系列。

我目前正在使用这样的东西:
(?:(d)=(1|2|4|8|16|32))|(?:(o)=(5|6|7|8))

然而,这给了我一些奇怪的结果。特别是,我使用下面的代码得到以下结果。

让我感到困惑的是,我得到了这些超出范围的范围,而且它们并不一致。例如,在比赛#1 中,超出范围是#3 和#4,但在比赛#2 中,超出范围是#1 和#2。

在我看来 1) 我使用了一个损坏的表达式,2) 这个 NSRegularExpression 要么是错误的,要么是 3) 我的理解有问题。

有什么帮助吗?
2012-01-20 11:01:56.027 TestRegex[95678:f803] -------------------------------
2012-01-20 11:01:56.027 TestRegex[95678:f803] Number of matches: 2
2012-01-20 11:01:56.028 TestRegex[95678:f803] Number of ranges = 5
2012-01-20 11:01:56.029 TestRegex[95678:f803] Range  0:  0  3 | d=4
2012-01-20 11:01:56.030 TestRegex[95678:f803] Range  1:  0  1 | d
2012-01-20 11:01:56.030 TestRegex[95678:f803] Range  2:  2  1 | 4
2012-01-20 11:01:56.031 TestRegex[95678:f803] Range  3: 2147483647  0 | <outside range>
2012-01-20 11:01:56.032 TestRegex[95678:f803] Range  4: 2147483647  0 | <outside range>
2012-01-20 11:01:56.032 TestRegex[95678:f803] Number of ranges = 5
2012-01-20 11:01:56.033 TestRegex[95678:f803] Range  0:  4  3 | o=5
2012-01-20 11:01:56.034 TestRegex[95678:f803] Range  1: 2147483647  0 | <outside range>
2012-01-20 11:01:56.035 TestRegex[95678:f803] Range  2: 2147483647  0 | <outside range>
2012-01-20 11:01:56.036 TestRegex[95678:f803] Range  3:  4  1 | o
2012-01-20 11:01:56.037 TestRegex[95678:f803] Range  4:  6  1 | 5

解析代码:
NSString *pat = regexTextField.text;
NSString *str = stringTextField.text;

NSError *err;
NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:pat
                                                                    options:NSRegularExpressionCaseInsensitive
                                                                      error:&err];

NSLog(@"-------------------------------");
if (err != nil) {
    NSLog(@"Error: %@", err.localizedDescription);
    NSLog(@"Error: %@", err.localizedFailureReason);
    NSLog(@"Error: %@", err.localizedRecoverySuggestion);
    return;
}

NSUInteger n = [re numberOfMatchesInString:str
                                   options:0
                                     range:NSMakeRange(0, str.length)];

NSLog(@"Number of matches: %u", n);

NSArray *matches = [re matchesInString:str 
                               options:0 
                                 range:NSMakeRange(0, str.length)];

for (NSTextCheckingResult *match in matches) {
    NSLog(@"Number of ranges = %d", match.numberOfRanges);
    for (int c = 0; c < match.numberOfRanges; ++c) {
        NSRange range = [match rangeAtIndex:c];
        NSString *matchStr;
        if (range.location >= str.length) {
            matchStr = @"<outside range>";
        } else {
            matchStr = [str substringWithRange:range];
        }
        NSLog(@"Range %2d: %2d %2d | %@", c, range.location, range.length, matchStr);
    }
}

最佳答案

你可以试试这个正则表达式:([a-z])=([0-9]+) .它匹配一个字母,后跟一个等号,然后是一个数字。两个捕获组来存储值。
获取所有匹配项,然后在第一个匹配组中,您得到字母,在第二个匹配组中得到数字。

因此,您拥有的正则表达式肯定很复杂,但不,实现有效。-(NSRange)rangeAtIndex:(NSUInteger)index;给定 0 时返回整个匹配范围,捕获组的范围如下。在下面的示例中,您将获得范围为索引 1 的字母和索引处的数字 2 .

NSString *str = stringTextField.text;
NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:@"([a-z])=([0-9]+)"
                                                                    options:NSRegularExpressionCaseInsensitive
                                                                      error:&err];
NSArray *matches = [re matchesInString:str 
                               options:0 
                                 range:NSMakeRange(0, str.length)];
for(NSTextCheckingResult *match in matches) {
    NSRange capture1 = [match rangeAtIndex:1]; // first capture group
    NSRange capture2 = [match rangeAtIndex:2]; // second one
    NSString *letter = [str substringWithRange:capture1];
    NSInteger number = [[str substringWithRange:capture2] integerValue];
    // ...
}

编辑:

回到您的示例,始终有 5 个范围:索引 0 处的整个匹配范围,以及捕获组的四个范围( (d)([1248]|16|32)(o)([5678]) ),分别从索引 1 到4. 必须以不同方式处理范围,以便第二次匹配 o=6 ,捕获组范围索引现在是 34 .这可以通过测试范围的 location 来完成。反对NSNotFound .
NSString *str = @"d=4,b=5,o=63";
NSRegularExpression *re = [NSRegularExpression
    regularExpressionWithPattern:@"(?:(d)=([1248]|16|32))|(?:(o)=([5678]))"
                                //    ^   ^                  ^   ^
                                //    1   2                  3   4
                         options:NSRegularExpressionAllowCommentsAndWhitespace
                           error:NULL];
NSArray *matches = [re matchesInString:str 
                               options:0 
                                 range:NSMakeRange(0, str.length)];
NSLog(@"Number of matches : %lu", [matches count]);
for(NSTextCheckingResult *match in matches) {
    NSLog(@"Number of ranges : %lu", match.numberOfRanges);
    NSLog(@"Globally matched from %lu, length = %lu", match.range.location, match.range.length);
    NSUInteger i = 1;
    NSRange capture1 = [match rangeAtIndex:i];
    NSRange capture2 = [match rangeAtIndex:i+1];
    while(capture1.location == NSNotFound) {
        i += 2;
        capture1 = [match rangeAtIndex:i];
        capture2 = [match rangeAtIndex:i+1];            
    }
    NSLog(@"Matched from %lu, length = %lu", capture1.location, capture1.length);
    NSLog(@"Matched from %lu, length = %lu", capture2.location, capture2.length);
    NSString *letter = [str substringWithRange:capture1];
    NSInteger number = [[str substringWithRange:capture2] integerValue];
    NSLog(@"%@ = %ld", letter, number);
}

2012-01-21 17:04:02.845 TestApp[3481:707] Number of matches : 2
2012-01-21 17:04:02.846 TestApp[3481:707] Number of ranges : 5
2012-01-21 17:04:02.846 TestApp[3481:707] Globally matched from 0, length = 3
2012-01-21 17:04:02.847 TestApp[3481:707] Matched from 0, length = 1
2012-01-21 17:04:02.847 TestApp[3481:707] Matched from 2, length = 1
2012-01-21 17:04:02.848 TestApp[3481:707] d = 4
2012-01-21 17:04:02.848 TestApp[3481:707] Number of ranges : 5
2012-01-21 17:04:02.848 TestApp[3481:707] Globally matched from 8, length = 3
2012-01-21 17:04:02.849 TestApp[3481:707] Matched from 8, length = 1
2012-01-21 17:04:02.849 TestApp[3481:707] Matched from 10, length = 1
2012-01-21 17:04:02.850 TestApp[3481:707] o = 6



范围总是被定义但并不总是有效,这取决于括号是否捕获了一些东西。

关于ios - NSRegularExpression : Proper regex for parsing d=4, b=5,o=63?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8946878/

相关文章:

Python 正则表达式 : how to parse repeated groups in a string?

java - 拆分字符串,如果它有数字

ios - 删除核心数据中一个属性等于另一个属性的记录

ios - 如何保存评级控制值?

ios - 如何使用 Swift 以编程方式设置 ios 中按钮的位置

ios - 如何更改 UINavigationItem 的 leftBarButtonItem 的大小

javascript - css webkit column 访问单列

ruby - ==~ 运算符是做什么的?

regex - Apache mod 重写简单重定向

javascript - 连接数组值