我正在尝试找到一个正则表达式来解析以下内容:
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
,捕获组范围索引现在是 3
和 4
.这可以通过测试范围的 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/