在希伯来语中,即使在谓词中使用“d”(变音符号不敏感)修饰符,NSPredicate仍然会忽略某些元音。我被告知解决方案是使用正则表达式进行搜索。
如何使用搜索字符串和“使用正则表达式”搜索包含元音的希伯来文本,忽略这些元音?
修改
换句话说,如果我想搜索以下文本,忽略破折号和星号,我将如何使用正则表达式?
示例文字:
我w-en * t t o o st * o * r * -e yes-ster * day。
编辑2:
基本上,我想:
编辑3:
以下是我实施搜索的方式:
//
// The user updated the search text
//
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString{
NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy];
if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
[filteredArray removeAllObjects];
NSPredicate *predicate;
if (controller.searchBar.selectedScopeButtonIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", searchString];
}else if (controller.searchBar.selectedScopeButtonIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[cd] %@", searchString];
}else if (controller.searchBar.selectedScopeButtonIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (dvarTorahContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}
for (Article *article in unfilteredResults) {
if ([predicate evaluateWithObject:article]) {
[self.filteredArray addObject:article];
}
}
[unfilteredResults release];
return YES;
}
编辑4:
我不需要使用正则表达式,只是建议这样做。如果你有另一种方法可行,那就去吧!
编辑5:
我将搜索修改为如下所示:
NSInteger length = [searchString length];
NSString *vowelsAsRegex = @"[\\u5B0-\\u55C4]*";
NSMutableString *modifiedSearchString = [searchString mutableCopy];
for (int i = length; i > 0; i--) {
[modifiedSearchString insertString:vowelsAsRegex atIndex:i];
}
if (controller.searchBar.selectedScopeButtonIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", modifiedSearchString];
}else if (controller.searchBar.selectedScopeButtonIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[cd] %@", modifiedSearchString];
}else if (controller.searchBar.selectedScopeButtonIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", modifiedSearchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (dvarTorahContent CONTAINS[cd] %@)", modifiedSearchString,modifiedSearchString,modifiedSearchString];
}
for (Article *article in unfilteredResults) {
if ([predicate evaluateWithObject:article]) {
[self.filteredArray addObject:article];
}
}
我在这里仍然遗漏了一些东西,我需要做些什么来完成这项工作?
编辑6:
好的,几乎就在那里。我需要再做两次更改才能完成。
我需要能够为正则表达式添加其他范围的字符,这可能会出现,而不是另一组中的字符。我试图将第一个范围更改为:
[\u05b0-\u05c, \u0591-\u05AF]?
有些东西告诉我这是不正确的。
另外,我需要其余的正则表达式不区分大小写。我需要使用什么修饰符与.*
正则表达式使其不区分大小写?
答案 0 :(得分:2)
希伯来语元音在Unicode中得到了很好的定义:Table of Hebrew characters and Marks
当您收到用户的输入字符串时,您可以在每个字符之间以及字符串之前和之后插入正则表达式[\u05B0-\u05C4]*
。 ([]
表示匹配任何包含的字符,*
表示匹配零个或多个表达式。)然后,您可以搜索文本块,将其用作正则表达式。此表达式允许您从用户的输入中查找确切的字符串。用户还可以指定此表达式可以找到的所需元音。
我认为不要试图忽略"在元音中,从大块文本和用户字符串中删除元音会更容易。然后你可以照常搜索字母。如果您不需要显示用户找到的发声文本,此方法就可以使用。
答案 1 :(得分:2)
这个答案可以解决问题所在。请阅读上下文。
事实证明,iOS可以使用Objective-C修饰符对NSPredicate使正则表达式不区分大小写。剩下的就是将两个范围结合起来。我意识到它们实际上是两个连续的范围。我的最终代码如下所示:
NSInteger length = [searchString length];
NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?"; //Cantillation: \u0591-\u05AF Vowels: \u05b0-\u05c
NSMutableString *modifiedSearchString = [searchString mutableCopy];
for (int i = length; i > 0; i--) {
[modifiedSearchString insertString:vowelsAsRegex atIndex:i];
}
if (controller.searchBar.selectedScopeButtonIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", modifiedSearchString];
}else if (controller.searchBar.selectedScopeButtonIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[c] %@", modifiedSearchString];
}else if (controller.searchBar.selectedScopeButtonIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[c] %@", modifiedSearchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[c] %@) OR (dvarTorahTitle CONTAINS[c] %@) OR (dvarTorahContent CONTAINS[c] %@)", modifiedSearchString,modifiedSearchString,modifiedSearchString];
}
[modifiedSearchString release];
for (Article *article in unfilteredResults) {
if ([predicate evaluateWithObject:article]) {
[self.filteredArray addObject:article];
}
}
请注意,正则表达式的范围部分会重复。这是因为单个字母上既可以有旋转标记,也可以有元音。现在,我可以搜索大写和小写的英语和希伯来语,有或没有元音和标记。
真棒!