在 NSPredicate 中使用带有 ISBN 数字示例的正则表达式令人困惑
Posted
技术标签:
【中文标题】在 NSPredicate 中使用带有 ISBN 数字示例的正则表达式令人困惑【英文标题】:Confusing on regular expression using in NSPredicate with ISBN numbers example 【发布时间】:2014-01-09 09:14:50 【问题描述】:Apple 文档在描述如何在 NSPredicate 中使用正则表达式时给出了一个示例。
NSArray *isbnTestArray = @[@"123456789X", @"987654321x", @"1234567890", @"12345X", @"1234567890X"];
NSPredicate *isbnPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '\\\\d10|\\\\d9[Xx]'"];
NSArray *isbnArray = [isbnTestArray filteredArrayUsingPredicate:isbnPredicate];
我的问题是为什么它使用\\\\d
而不是\\d
或\d
?
【问题讨论】:
【参考方案1】: 数字的正则表达式模式是\d
。
在谓词'…'
的文字字符串中,每个反斜杠都必须被转义,所以你得到\\d
。
谓词在文字NSString
中定义,因此反斜杠必须再次转义,得到\\\\d
。
如果在谓词中使用%@
格式而不是文字字符串,则可以避免一个转义步骤:
NSString *pattern = @"\\d10|\\d9[Xx]";
NSPredicate *isbnPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
对谓词中的所有变量部分使用%@
通常会更好,因为它可以避免
各种引用和转义问题。
【讨论】:
另一个问题,为什么我们可以写成NSString *pattern = @"\\d10|\\d9[Xx]";
而不是NSString *pattern = @"\\\\d10|\\\\d9[Xx]";
@KudoCC: NSString *pattern = @"\\\\d10|\\\\d9[Xx]"
存储为字符串"\\d10|\\d9[Xx]"
,这将匹配文字反斜杠字符后跟 10 个“d”字符。
但是为什么它不会在[NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
中再次被转义?
@KudoCC:谓词在内部表示为 NSComparisonPredicate ,而不是字符串,因此不会有额外的转义。您不必担心。【参考方案2】:
大多数编程语言使用\
作为转义序列。
当你这样写时:
SELF MATCHES '\\\\d10|\\\\d9[Xx]'
每个\都会转义下一个字符,它会变成:
SELF MATCHES '\\d10|\\d9[Xx]'
为什么不使用 \d ?
如果你像这样使用:
SELF MATCHES '\d10|\d9[Xx]'
在正则表达式中会改为:
SELF MATCHES 'd10|d9[Xx]'
为什么不使用 \d ?
如果你像这样使用:
SELF MATCHES '\\d10|\\d9[Xx]'
在正则表达式中会改为:
SELF MATCHES '\d10|\d9[Xx]'
但在正则表达式中,\d
将被视为转义序列,并将其视为d10|d9[Xx]
【讨论】:
"如果你使用:SELF MATCHES '\d10|\d9[Xx]' 它会变成这样:SELF MATCHES 'd10|d9 [Xx]'",是真的吗? @KudoCC: 表示它将被视为转义序列。以上是关于在 NSPredicate 中使用带有 ISBN 数字示例的正则表达式令人困惑的主要内容,如果未能解决你的问题,请参考以下文章
带有核心数据的 NSPredicate,在字符串属性中搜索带有边界的单词
如何在 iOS 的核心数据中创建和使用带有查询的 NSPredicate?