NSRegularExpression分隔段落

时间:2013-01-28 18:54:08

标签: ios objective-c regex nsregularexpression

考虑这个文字:

Paragraph 1: Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. 

Paragraph 2 Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat.







Paragraph 3 Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat.

在ObjC中,在阅读上述文本时,段落1和段落2之间有两个\n\n行间距。但在第2段和第3段之间有超过3个行空格\n\n\n\n

我希望有一个NSRegularExpression模式,它会读取并返回那些完全忽略行间距的段落。

NSString *pattern = @"\n(*\n)\n";

NSRegularExpression* regex1 = [[NSRegularExpression alloc] initWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil];

NSArray *array = [regex1 matchesInString:p options:0 range:NSMakeRange(0, [p length])];
for(NSTextCheckingResult *tcr in array){
    NSTextCheckingResult *tcr = [regex1 firstMatchInString:p options:0 range:NSMakeRange(0, p.length)];
    NSRange matchRange = [tcr rangeAtIndex:1];
    NSString *amatch = [p substringWithRange:matchRange];
    NSLog(@"Found string: %@", amatch);
}

我是NSRegularExpression的新手,任何对更好教程的引用都会很棒。在这种情况下,这是在上述问题中采用它的正确方法。

4 个答案:

答案 0 :(得分:4)

您不需要NSRegularExpression来执行此操作。在NSString中有很多非常有用的自然语言解析函数。

最好的方法是枚举像这样的字符串......

NSString *string = @"Paragraph 1: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n\nParagraph 2 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n\n\n\n\n\n\n\n\nParagraph 3 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";

NSMutableArray *paragraphs = [NSMutableArray array];

[string enumerateSubstringsInRange:NSMakeRange(0, string.length) 
                           options:NSStringEnumerationByParagraphs 
                        usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    [paragraphs addObject:substring];
}];

for (NSString *paragraph in paragraphs) {
    NSLog(@"%@", paragraph);
}

这将采用每个段落并将其放入段落NSMutableArray。

这不需要任何解析或正则表达式等......它也可能比你能写的任何东西都快,因为它是一个原生函数。

答案 1 :(得分:1)

我相信使用标准NSString方法可以更轻松地完成:

NSArray *allParagraphs = [text componentsSeparatedByString:@"\n\n"];

NSCharacterSet *charactersToTrim = [NSCharacterSet whitespaceAndNewlineCharacterSet];
for (NSString *paragraph in allParagraphs) {
    NSString *trimmedParagraph = 
            [paragraph stringByTrimmingCharactersInSet:charactersToTrim];
}

或者,如果您想使用正则表达式,请尝试以下方法:

"(.*?)(\\n{2,}|$)"

保留所有符号,直到找到两个或多个新行或文件结尾

修改

NSRegularExpression *regexp =
        [NSRegularExpression regularExpressionWithPattern:@"(.*?)(\\n{2,}|$)"
                                                  options:NSRegularExpressionDotMatchesLineSeparators
                                                    error:nil];
[regexp enumerateMatchesInString:TEST_STRING
                         options:0
                           range:NSMakeRange(0, TEST_STRING.length)
                      usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop){
                          NSLog(@"%@", [TEST_STRING substringWithRange:[result rangeAtIndex:1]]);
                      }];

答案 2 :(得分:0)

我无法帮助您进行NSRegularExpression匹配和替换,但我相信您正在寻找的正则表达式是\\n(\\n)+

您需要两次转义换行符。一次为C字符串,一次为正则表达式。 +字符表示前一组中的一个或多个。

答案 3 :(得分:0)

以下工作。我还使用enumerateMatchesInString来查找匹配项。

NSString *pattern = @"(\\A|\\n\\s*\\n)(.*?\\S[\\s\\S]*?\\S)(?=(\\Z|\\s*\\n\\s*\\n))";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:pattern
                                                                  options:NSRegularExpressionCaseInsensitive
                                                                    error:&error];

[regex enumerateMatchesInString:input
                        options:0
                          range:NSMakeRange(0, [input length])
                     usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
                         NSString *match = [input substringWithRange:[result rangeAtIndex:2]];
                         NSLog(@"match = '%@'", match);
                     }];

这不仅返回两个换行符之间的字符串(忽略返回之间的任何额外空格),还返回第一个(即字符串的开头和两个换行符的第一个序列之间)和最后一个(即在两个换行符的最后一个序列和字符串的结尾之间。