2016-03-09 74 views
23

我想知道isLike:實際上對NSString有什麼影響,並遇到了麻煩。蘋果的own documentation很模糊:NSString是什麼類似:實際上是這樣嗎?

返回一個布爾值,指示接收者是否是「喜歡」 另一個定的對象。

...

通過NSObject方法 返回NO提供此方法的默認實現。 NSString也提供了這種方法的實現, 如果接收方匹配 對象描述的模式,則返回YES

它提到了一個「模式」,但有一些基本的測試,它似乎沒有使用正則表達式。這種情況下的模式格式究竟是什麼?

+2

它與[NSPredicate'中的'LIKE'運算符的行爲匹配嗎?](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html #// apple_ref/DOC/UID/TP40001795-215868)? –

+0

@JoshCaswell'*'按照那裏描述的方式工作,但它在一定程度上也可以進行子串比較...所以「FooBar」就像「Foo」 – Earlz

+1

@Earlz,我試過'[@「FooBar」isLike:@「Foo」] '但得到了一個錯誤的結果。 – cdlane

回答

10

正如其他已經公佈,蘋果公司的文檔不介紹的詳細[NSString isLike:]行爲所看到here

的默認實現NSObject方法提供的這個方法返回NO。 NSString也提供了這個方法的實現,如果接收者匹配由object描述的模式,返回YES。

正如其他人建議它可能基於NSPredicate。如果是這樣則有可能使用NSComparisonPredicate具有操作員類型NSLikePredicateOperatorType描述here

NSMatchesPredicateOperatorType

全正則表達式匹配謂詞。

適用於OS X v10.4及更高版本。

NSLikePredicateOperatorType

比賽斷言,在行爲SQL LIKE類似的簡單子集。

適用於OS X v10.4及更高版本。

雖然功能可能是正則表達式的簡單子集,但語法完全不同。我在OS X 10.10本地測試了以下內容。5日:

- (NSString *)escapeString:(NSString *)value { 
    return [value stringByReplacingOccurrencesOfString:@"\\" withString:@"\\\\"]; 
} 

- (void)is:(NSString *)value like:(NSString *)pattern note:(NSString *)note { 
    NSLog(@"[@\"%@\" isLike:@\"%@\"] == %@ // %@", 
      [self escapeString:value], 
      [self escapeString:pattern], 
      ([value isLike:pattern] ? @"true" : @"false"), 
      note); 
} 

- (void)testAll { 
    // each note contains result on OS X 10.10.5 on 20160503 
    [self is:@"foo" like:@"f*" note:@"true, '*' wildcard works like file globbing, not RE"]; 
    [self is:@"foo" like:@"foo*" note:@"true, '*' is zero or more"]; 
    [self is:@"foo" like:@"f?o" note:@"true, '?' wildcard works like file globbing, not RE"]; 
    [self is:@"foo" like:@"f?" note:@"false, not more then one"]; 
    [self is:@"foo" like:@"f?oo" note:@"false, not less than one"]; 
    [self is:@"foo" like:@"Foo" note:@"false, is case-sensitive (also see isCaseInsensitiveLike:)"]; 
    [self is:@"foo" like:@"[Ff]oo" note:@"true, supports character classes"]; 
    [self is:@"foo" like:@"[^F]oo" note:@"false, does not support RE negation in character classes"]; 
    [self is:@"foo" like:@"[a-z]oo" note:@"true, supports ranges"]; 
    [self is:@"foo" like:@"[[:lower:]]oo" note:@"false, does not support POSIX named classes"]; 
    [self is:@"]oo" like:@"[]]oo" note:@"false, does not support ']' as first character in a class"]; 
    [self is:@"]oo" like:@"[\\]]oo" note:@"true, backslash to escape interpretation of ']' as end of class"]; 
    [self is:@"[oo" like:@"\\[oo" note:@"true, backslash to escape interpretation as start of class"]; 
    [self is:@"-oo" like:@"[x\\-z]oo" note:@"true, supports escape of '-' in character classes"]; 
    [self is:@"?oo" like:@"\\?oo" note:@"true, escape with backslash"]; 
    [self is:@"foo" like:@"\\?oo" note:@"false, this is not just wildcard matching"]; 
    [self is:@"*oo" like:@"\\*oo" note:@"true, escape with backslash"]; 
    [self is:@"foo" like:@"\\*oo" note:@"false, this is not just wildcard matching"]; 
    [self is:@"\\foo" like:@"\\\\*oo" note:@"true, escape backslash with another backslash"]; 
} 

而這個代碼將產生以下結果:

[@"foo" isLike:@"f*"] == true // true, '*' wildcard works like file globbing, not RE 
[@"foo" isLike:@"foo*"] == true // true, '*' is zero or more 
[@"foo" isLike:@"f?o"] == true // true, '?' wildcard works like file globbing, not RE 
[@"foo" isLike:@"f?"] == false // false, not more then one 
[@"foo" isLike:@"f?oo"] == false // false, not less than one 
[@"foo" isLike:@"Foo"] == false // false, is case-sensitive (also see isCaseInsensitiveLike:) 
[@"foo" isLike:@"[Ff]oo"] == true // true, supports character classes 
[@"foo" isLike:@"[^F]oo"] == false // false, does not support RE negation in character classes 
[@"foo" isLike:@"[a-z]oo"] == true // true, supports ranges 
[@"foo" isLike:@"[[:lower:]]oo"] == false // false, does not support POSIX named classes 
[@"]oo" isLike:@"[]]oo"] == false // false, does not support ']' as first character in a class 
[@"]oo" isLike:@"[\\]]oo"] == true // true, backslash to escape interpretation of ']' as end of class 
[@"[oo" isLike:@"\\[oo"] == true // true, backslash to escape interpretation as start of class 
[@"-oo" isLike:@"[x\\-z]oo"] == true // true, supports escape of '-' in character classes 
[@"?oo" isLike:@"\\?oo"] == true // true, escape with backslash 
[@"foo" isLike:@"\\?oo"] == false // false, this is not just wildcard matching 
[@"*oo" isLike:@"\\*oo"] == true // true, escape with backslash 
[@"foo" isLike:@"\\*oo"] == false // false, this is not just wildcard matching 
[@"\\foo" isLike:@"\\\\*oo"] == true // true, escape backslash with another backslash 

所以isLike:似乎支持?*類似文件,反斜槓\通配符轉義特殊解釋。它還支持使用[]的字符類別,範圍用-定義。反斜槓以避開開口[,並且反斜槓在類內跳過]-

8

NSScriptWhoseTest.h提供多一點信息:

@interface NSObject (NSComparisonMethods) 
... 

- (BOOL)isLike:(NSString *)object; 
    // argument should be a string using simple shell wildcards (* and ?). 
    // (e.g. "Stev*" or "N?XT"). 
    // Returns NO if receiver is not an NSString. 

- (BOOL)isCaseInsensitiveLike:(NSString *)object; 

@end 
+1

連同@JoshCaswell鏈接到[NSPredicate](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-215868 ),很可能是'*'和'?'是唯一的模式字符。請注意'\'也允許轉義:'[@「F?oo」isLike:@「\\ F \\?oo」]'是'true' –

+0

我後來發現這是嚴重不完整的。它還允許字符類,即「isLike:」[abc] foobar「'將爲」afoobar「和」cfoobar「返回true, – Earlz

相關問題