0

如何使用 NSPredicate 过滤以数字或符号开头的字符串到 NSArray。

例子:

数组 = {“约翰”、“玛丽”、“阿罗多”、“1约翰”、“+玛丽”}

到 newArray = {"1John," "+Mary"}

4

3 回答 3

6

这里有4种方法来做到这一点。所有示例都使用了否定字符类。您的要求是过滤掉数字和符号,但您也可以说要过滤掉以非字母字符开头的单词。

- (void)testFilterArray0
{
    predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^a-zA-Z].*"];
    filtered = [unfiltered filteredArrayUsingPredicate:predicate];
    STAssertTrue([filtered isEqualToArray:expected], nil);
}

- (void)testFilteredArray1
{
    predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^\\p{L}].*"];
    filtered = [unfiltered filteredArrayUsingPredicate:predicate];
    STAssertTrue([filtered isEqualToArray:expected], nil);
}

- (void)testFilteredArray2
{
    predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^\\p{Letter}].*"];
    filtered = [unfiltered filteredArrayUsingPredicate:predicate];
    STAssertTrue([filtered isEqualToArray:expected], nil);
}

- (void)testFilteredArray3
{
    predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"[^\\p{General_Category=Letter}].*"];
    filtered = [unfiltered filteredArrayUsingPredicate:predicate];
    STAssertTrue([filtered isEqualToArray:expected], nil);
}
于 2013-02-27T22:50:37.817 回答
0

它不使用 NSPredicate,但它完成了工作

NSIndexSet *indexSet = [array indexesOfObjectsPassingTest:^BOOL(NSString *name, NSUInteger idx, BOOL *stop) {
    unichar ch = [name characterAtIndex:0];
    BOOL isLetter = (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122);
    return !isLetter;
}];

NSArray *newArray = [array objectsAtIndexes:indexSet];

您可能需要仔细检查块中的返回条件,因为我没有测试它。

于 2013-02-27T19:57:15.080 回答
0

您可以使用带有正则表达式的谓词来完成您所追求的。

通常,您正在寻找的正则表达式模式"[chars].*"将匹配任何以 c、h、a、r 或 s 开头的字符串 - 在示例中。您将替换您想要匹配的实际字符。

为了使结构更清晰,您可以创建一个包含要匹配的实际字符的字符串、一个带有正则表达式模式的字符串,最后是谓词。

如果您对正则表达式和谓词非常熟悉,您当然可以将其全部压缩到一行代码。

NSString *matchChars  = @"0123456789+-,."; // Add other characters you want to match

NSString *regexString  = [NSString stringWithFormat:@"[%@].*", matchChars];

NSPredicate *pred = [NSPredicate predicateWithFormat:@"self matches[cd] %@", regexString];
于 2013-02-27T20:43:36.927 回答