【问题标题】:Searching for the words with brackets placed around them in iOS在 iOS 中搜索带有括号的单词
【发布时间】:2013-05-25 19:46:54
【问题描述】:

我正在尝试在一组文本中搜索所有带有括号的单词,并在 iOS 中将其更改为斜体。我正在使用此代码在文本中搜索括号:

static inline NSRegularExpression * ParenthesisRegularExpression() {
    static NSRegularExpression *_parenthesisRegularExpression = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _parenthesisRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"\\[[^\\(\\)]+\\]" options:NSRegularExpressionCaseInsensitive error:nil];
    });

    return _parenthesisRegularExpression;
}

我正在使用它向我展示匹配项:

NSRange matchRange = [result rangeAtIndex:0];
NSString *matchString = [[self.markerPointInfoDictionary objectForKey:@"long_description"] substringWithRange:matchRange];
NSLog(@"%@", matchString);

但它正在返回我从文本组中第一个 [ 到最后一个 ] 的所有文本。中间有很多括号。

我正在使用此代码将文本更改为斜体:

-(TTTAttributedLabel*)setItalicTextForLabel:(TTTAttributedLabel*)attributedLabel fontSize:(float)Size
{
    [attributedLabel setText:[self.markerPointInfoDictionary objectForKey:@"long_description"] afterInheritingLabelAttributesAndConfiguringWithBlock:^NSMutableAttributedString *(NSMutableAttributedString *mutableAttributedString)
     {
         NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);
         NSRegularExpression *regexp = ParenthesisRegularExpression();
         UIFont *italicSystemFont = [UIFont italicSystemFontOfSize:Size];
         CTFontRef italicFont = CTFontCreateWithName((__bridge CFStringRef)italicSystemFont.fontName, italicSystemFont.pointSize, NULL);
         [regexp enumerateMatchesInString:[mutableAttributedString string] options:0 range:stringRange usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
             NSRange matchRange = [result rangeAtIndex:0];
             NSString *matchString = [[self.markerPointInfoDictionary objectForKey:@"long_description"] substringWithRange:matchRange];
             NSLog(@"%@", matchString);
             if (italicFont) {
                 [mutableAttributedString removeAttribute:(NSString *)kCTFontAttributeName range:result.range];
                 [mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)italicFont range:result.range];
                 CFRelease(italicFont);
                 NSRange range1 = NSMakeRange (result.range.location, 1);
                 NSRange range2 = NSMakeRange (result.range.location + result.range.length -2 , 1);
                 [mutableAttributedString replaceCharactersInRange:range1 withString:@""];
                 [mutableAttributedString replaceCharactersInRange:range2 withString:@""];
             }
         }];
         return mutableAttributedString;
     }];

    return attributedLabel;
}

顺便说一句,我的文本看起来像这样:

[hello] welcome [world], my [name] is [lakesh]

结果如下所示:

match string is [hello]
match string is [world]
match string is  is [lak

then crash..

需要一些指导来告诉我我的错误。

【问题讨论】:

  • 你的崩溃日志是什么?您是否使用原始未修改字符串的匹配范围修改字符串?如果是这样,您将超出界限。你应该
  • 崩溃日志严重过剩...

标签: ios regex nsregularexpression


【解决方案1】:

您的崩溃日志是什么? 您是否使用原始未修改字符串的匹配范围修改字符串?如果是这样,您将在完成之前跑出界限。

您可以考虑其他几种方法。您需要一次删除一个,并停止尝试让您的代码在同一个地方进行斜体和字符替换。这让你很困惑。

你的斜体部分很好。 但是您需要使用额外的迭代逻辑来删除字符,以便在删除每个字符后从 niw 较短的字符串中获取新的匹配范围。

【讨论】:

  • 如何拆分斜体和字符替换?任何想法?需要哪些额外的迭代逻辑?
【解决方案2】:

我没有想过你展示的代码,但是你的正则表达式似乎太贪心了:

@"\\[[^\\(\\)]+\\]"

这匹配括号“[]”之间的 1-n 个字符。字符由一个字符类定义,该类表示“除括号外的所有字符”,即除“()”之外。

换句话说,你的字符类也匹配括号字符。结果是您的表达式匹配第一个“[”和最后一个“]”之间的所有内容。

我建议你改用以下正则表达式:

@"\\[[^\\[\\]]+\\]"

如果您没有嵌套括号,您甚至可以将其简化为:

@"\\[[^\\]]+\\]"


编辑

这是您提供的代码和示例输入文本的简化版本,但使用了我建议的正则表达式。在我的环境中,这非常有效,它会在我的调试输出窗口中打印 4 行。不知道是什么原因导致你的崩溃,所以建议你开始逐步简化自己的代码,直到找到问题为止。

NSString* mutableAttributedString = @"[hello] welcome [world], my [name] is [lakesh]";
NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);
NSRegularExpression* regexp = [[NSRegularExpression alloc] initWithPattern:@"\\[[^\\]]+\\]" options:NSRegularExpressionCaseInsensitive error:nil];
[regexp enumerateMatchesInString:mutableAttributedString
                         options:0
                           range:stringRange
                      usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
 {
   NSRange matchRange = [result rangeAtIndex:0];
   NSString* matchString = [mutableAttributedString substringWithRange:matchRange];
   NSLog(@"%@", matchString);
 }
 ];

与您的代码的主要区别是:

  • 我不使用TTTAttributedLabel
  • 我不使用NSMutableAttributedString
  • 我不使用self.markerPointInfoDictionary
  • 我没有if (italicFont) 代码块

所以你的问题应该在这些领域之一。

【讨论】:

  • +1;我把这个正则表达式放到了我的测试应用程序中(我也试图解决这个问题),你首先得到了它。好工作!正则表达式可能非常棘手。我最初的回答想法是使用 NSScanner。
  • @MichaelDautermann 谢谢。 NSPredicate 也很有用,但反斜杠的数量需要加倍,使得正则表达式更加模糊。
  • 它正确地抓住了第一个括号,但之后是错误的......错过了一个......编辑了问题。
  • 如果没有示例文本,就无法知道它是否足够正确。特别是处理重叠和悬空的打开或关闭括号
  • 首先感谢您的回复和搜索。我面临的问题是我正在同时进行搜索,斜体和替换..您有什么解决方案可以确保这三个正确发生...
猜你喜欢
  • 2011-09-08
  • 2012-01-23
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多