ios解析txt电子书

昨天上线新版本因为Other-Other账号审核被拒了,估计要等待几天了,正好抽时间把最近写的东西整理一下。

附上APP地址: 一阅阅读有想看小说的小伙伴可以试下 支持换源 支持自定义书源

言归正传,TXT电子书解析主要靠正则,筛选出文件内所有章节,并划分range,对于正则表达式的基础内容我不做过多描述,各位有兴趣可以去 菜鸟教程正则表达式自己去看下一下。

正则

(\\s+?)([#☆、【0-9]{0,10})(第[0-9零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟\\s]{1,10}[章节回集卷])(.*)

用法


+ (void)parseLocalBookWithFilePath:(NSString *)filePath bookId:(NSString *)bookId success:(void (^)(NSArray<TJChapterModel *> * _Nonnull chapters))success failure:(TJFailureHandler)failure {
    if (!filePath) {
        !failure ?: failure([NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:@{NSUnderlyingErrorKey : @"文件路径为空"}]);
        return;
    }
    
    if (![filePath hasSuffix:@"txt"]) {
        !failure ?: failure([NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:@{NSUnderlyingErrorKey : @"文件格式不正确"}]);
        return;
    }
    
    NSString *content = [self contentWithFilePath:filePath];
    if (TJIsEmptyObject(content)) {
        !failure ?: failure([NSError errorWithDomain:NSCocoaErrorDomain code:-1 userInfo:@{NSUnderlyingErrorKey : @"书籍内容为空或者书籍格式错误"}]);
        return;
    }
    NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:kParseLocalBookPattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSArray *matches = [expression matchesInString:content options:NSMatchingReportCompletion range:NSMakeRange(0, content.length)];
    NSMutableArray *chapters = [[NSMutableArray alloc] init];
    if (matches.count == 0) {
        // 全书分为一章
        TJChapterModel *chapter = [[TJChapterModel alloc] init];
        chapter.chapterId = [bookId stringByAppendingFormat: @"1000000"];
        chapter.chapterIndex = 1;
        chapter.chapterName = @"开始";
        chapter.content = content;
        [chapters addObject:chapter];
    } else {
        // 当前标题在全文中的位置
        NSRange currentRange = NSMakeRange(0, 0);
        // 当前章节编号
        NSInteger chapterIndex = 1;
        // 循环处理章节
        for (NSInteger i = 0; i < matches.count; i++) {
            @autoreleasepool {  // 自动释放池保证瞬时内存不会过高
                NSTextCheckingResult *result = matches[i];
                // 下一个标题在全文中的位置
                NSRange resultRange = result.range;
                // 截取两个标题之间内容为当前章节内容
                NSString *chapterContent = [content substringWithRange:NSMakeRange(currentRange.location + currentRange.length, resultRange.location - currentRange.location - currentRange.length)];
                if (!TJIsEmptyObject(chapterContent) && resultRange.length <= 70) {
                    // 章节内容不为空并且章节标题长度不超过70
                    TJChapterModel *chapterModel = [[TJChapterModel alloc] init];
                    chapterModel.chapterIndex = chapterIndex;
                    chapterModel.chapterId = [bookId stringByAppendingFormat: [NSString stringWithFormat:@"%@", @(1000000 + chapterIndex)]];
                    chapterModel.chapterName = (chapterIndex == 1) ? @"开始" : [[content substringWithRange:currentRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    chapterModel.content = [self resetContent:chapterContent];
                    [chapters addObject:chapterModel];
                    chapterIndex += 1;
                    currentRange = resultRange;
                }
            };
        }
        NSString *endChapterContent = [content substringWithRange:NSMakeRange(currentRange.location + currentRange.length, content.length - currentRange.location - currentRange.length)];
        if (!TJIsEmptyObject(endChapterContent)) {
            // 最后一章
            TJChapterModel *endChapterModel = [[TJChapterModel alloc] init];
            endChapterModel.chapterIndex = chapterIndex;
            endChapterModel.chapterId = [bookId stringByAppendingFormat: [NSString stringWithFormat:@"%@", @(1000000 + chapterIndex)]];
            endChapterModel.chapterName = [[content substringWithRange:currentRange] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            endChapterModel.content = [self resetContent:endChapterContent];
            [chapters addObject:endChapterModel];
        }
    }
    if (chapters.count > 0 && success) {
        success(chapters);
    }
}

/// 处理章节内容
/// @param content 内容
+ (NSString *)resetContent:(NSString *)content {
    if (!content || content.length == 0) {
        return @"";
    }
    // 替换单换行
    content = [content stringByReplacingOccurrencesOfString:@"r" withString:@""];
    
    // 替换换行和多个换行(换行加空格)
    NSRegularExpression *regularExpression = [[NSRegularExpression alloc] initWithPattern:@"\\s*\\n+\\s*" options:NSRegularExpressionCaseInsensitive error:nil];
    content = [regularExpression stringByReplacingMatchesInString:content options:NSMatchingReportProgress range:NSMakeRange(0, content.length) withTemplate:@"\n  "];
    
    // 去掉首尾空格和换行
    content = [content stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    
    // 章节开头添加空格
    content = [@"  " stringByAppendingString:content];
    
    return content;
}


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容