【问题标题】:Complex regex text modifiaction复杂的正则表达式文本修改
【发布时间】:2014-01-16 20:01:07
【问题描述】:

您好,我遇到了一个复杂的正则表达式情况。

mainString = @"Main Term (Rounded) [Square] ~a~d~j~."

我需要像这样返回它

modifiedString* = @"Main Term (Rounded) [Square] adj."  

所以~ 之后的每个字符都必须是斜体或任何属性。
而且我需要修改后"adj."的范围,以便我可以添加属性。

谢谢。

NSError *error3 = nil;
    NSRegularExpression *SHRegex = [NSRegularExpression regularExpressionWithPattern:@"\\~(.|)" options:0 error:&error3];
    NSArray *matches3 = [SHRegex matchesInString:mainString options:0 range:NSMakeRange(0, [mainString length])];
    NSUInteger *numberOfMatches =  [SHRegex numberOfMatchesInString:mainString options:0 range:NSMakeRange(0, mainString.length)];

    NSString *modifiedString = [SHRegex stringByReplacingMatchesInString:mainString options:0 range:NSMakeRange(0, [string length]) withTemplate:@""];
for (NSTextCheckingResult *match in matches3) {
        NSRange matchRange = [match range];
        NSRange firstHalfRange = [match rangeAtIndex:1];
        //NSRange secondHalfRange = [match rangeAtIndex:2];
        [string addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:0 green:0 blue:0 alpha:1] range:matchRange];
        //[string addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:firstHalfRange];
    }

【问题讨论】:

  • 澄清一下:您想从字符串中删除所有~ 字符,并返回被这些字符包围的所有字符的位置吗?它总是~a~b~c~d~ 还是~abc~ d ~e~ - 在后一种情况下,您是否希望返回abc d e? `d` 会成为“特殊匹配字符”的一部分吗?你有~a~d~j~. 并希望adj. 是“特别的”。这是否意味着您只需要一个波浪号特殊字符之前?
  • 它可以是Main ~a~d~j~. Sub ~a~d~v~.,是的,我想删除~,并返回剩余adj.adv. 的范围或位置。 MainSub 并不特殊。

标签: ios regex nsstring nsregularexpression


【解决方案1】:

下面的代码应该做你想做的事。它创建一个属性字符串 其中波浪字符被删除,并且一个属性被添加到 波浪号后面的字符。我添加了一些希望 解释它是如何工作的。

NSString *mainString = @"Main Term (Rounded) [Square] ~a~d~j~.";
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:mainString];

NSError *error = nil;
// Pattern that matches a tilde followed by an arbitrary character:
NSString *pattern = @"(\\~)(.)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];

__block NSUInteger offset = 0;
[regex enumerateMatchesInString:mainString options:0 range:NSMakeRange(0, [mainString length])
                     usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
      NSRange firstHalfRange = [result rangeAtIndex:1];  // range of the tilde
      NSRange secondHalfRange = [result rangeAtIndex:2]; // range of the following character
      // Adjust locations according to the string modifications:
      firstHalfRange.location += offset;
      secondHalfRange.location += offset;
      // Set attribute for the character:
      [attrString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:1 green:0 blue:0 alpha:1] range:secondHalfRange];
      // Remove the tilde:
      [[attrString mutableString] deleteCharactersInRange:firstHalfRange];
      // Update offset:
      offset -= firstHalfRange.length;
}];

更新以回应您的评论:以下代码匹配两种模式(波浪号或插入符号后跟一个字符)并使用不同的属性进行替换。

NSString *mainString = @" ~a^b~c^d";
NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:mainString];

NSError *error = nil;
NSString *pattern = @"(\\~|\\^)(.)";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];

__block NSUInteger offset = 0;
[regex enumerateMatchesInString:mainString options:0 range:NSMakeRange(0, [mainString length])
                     usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
     NSRange firstHalfRange = [result rangeAtIndex:1];
     NSRange secondHalfRange = [result rangeAtIndex:2];
     NSString *firstMatch = [mainString substringWithRange:firstHalfRange];
     // Adjust locations according to the string modifications:
     firstHalfRange.location += offset;
     secondHalfRange.location += offset;
     // Set color attribute for the character:
     if ([firstMatch isEqualToString:@"~"]) {
         [attrString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:1 green:0 blue:0 alpha:1] range:secondHalfRange];
     } else {
         [attrString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:0 green:1 blue:0 alpha:1] range:secondHalfRange];
     }
     [[attrString mutableString] deleteCharactersInRange:firstHalfRange];
     // Update offset:
     offset -= firstHalfRange.length;
}];

【讨论】:

  • 非常感谢。这就是我需要的。
  • 我的数据库结构在每个应该是下标的字符之前都有一个波浪号。多亏了你,现在完成了。但我也希望^ 之后的每个字符都是上标。添加相同的代码可以完成这项工作,但如果相同的条目有两种变化,它会崩溃为indexOutOfRange...有什么建议吗?
【解决方案2】:

您的正则表达式实施是否支持正向回溯?

如果是这样,您可以使用(?<=~)(.) 分别匹配adj.

【讨论】:

    猜你喜欢
    • 2015-02-21
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多