NSRegularExpression似乎无法识别表达式中的符号“和}

时间:2013-07-04 13:15:59

标签: objective-c regex nsregularexpression

我有一个适用于RegExr的正则表达式,但不适用于Objective-C中的NSRegularExpression。问题在于“和”符号,它是我想要搜索的字符串的一部分。 我的正则表达式:

(?<=\"Here\":\")(.*?)(?=\"})

使用这个表达式,Xcode表示“expect:”,并且在\}前面有\,而Xcode也表示它无法识别}。我将所有这些变体与RegExr一起使用。

对于这样的字符串:

{"Something":"Something else", "Here" : "What I want is between these quotation marks"}

我抬头看了documentation,但我没有找到关于这些符号的任何内容。

我的代码是:

NSRegularExpression *regEx = [NSRegularExpression regularExpressionWithPattern:@"(?<=\"Here\":\")(.*?)(?=\"})"options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regEx matchesInString:stringToSearch options:0 range:NSMakeRange(0, [stringToSearch length])];
[matches count] // Returns 0

那么我的错误在哪里?也许所有的表达都是错的,RegExr就是问题?

提前致谢。

2 个答案:

答案 0 :(得分:3)

您应该使用NSJSONSerialization来解析您的JSON:

例如

NSData *data = ...  // load your {"Something":"Something else", "Here" : "What I want is between these quotation marks"}

NSError *error;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (error)
    NSLog(@"%s: JSONObjectWithData error: %@", __FUNCTION__, error);

NSLog(@"value for Something: %@", dictionary[@"Something"]);
NSLog(@"value for Here: %@", dictionary[@"Here"]);

使用正则表达式解析JSON本身就很脆弱。例如,您明确假设JSON中的冒号周围没有空格。但可能有(事实上,在你的例子中,有)。同样,假设“Here”的值是最后一项(因此您可以查找引号后跟关闭括号,而在将来某个日期它可能后面跟一个逗号,而不是一个结束)可能是不谨慎的。支撑)。更糟糕的是,理论上可能(虽然极不可能)字符串值本身会有一个引号和右括号,所以你真的应该检查未转义的引号。

虽然您可以修复正则表达式,但使用JSON解析器可以避免所有这些必须构建为复杂正则表达式的附加逻辑。

答案 1 :(得分:1)

您的模式应如下所示:

@"(?<=\"Here\":\")(.*?)(?=\"\\})"

由于"用作NSString的分隔符,您必须将它们转义(即在字符串中的所有\之前添加")。

编辑:正如MartinR在评论中指出的那样,您还需要使用两个斜杠}来转义\\,因为它是正则表达式中的特殊字符。

这应该非常清楚地显示语法着色:

code syntax colored

完整代码:

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=\"Here\":\")(.*?)(?=\"})"
                                                                   options:NSRegularExpressionCaseInsensitive // or whatever options you want to use
                                                                     error:&error];