昨天上線新版本因?yàn)镺ther-Other賬號(hào)審核被拒了,估計(jì)要等待幾天了侈询,正好抽時(shí)間把最近寫的東西整理一下。
附上APP地址: 一閱閱讀有想看小說的小伙伴可以試下 支持換源 支持自定義書源
言歸正傳,TXT電子書解析主要靠正則牡昆,篩選出文件內(nèi)所有章節(jié),并劃分range摊欠,對(duì)于正則表達(dá)式的基礎(chǔ)內(nèi)容我不做過多描述丢烘,各位有興趣可以去 菜鳥教程正則表達(dá)式自己去看下一下。
正則
(\\s+?)([#☆些椒、【0-9]{0,10})(第[0-9零一二兩三四五六七八九十百千萬(wàn)壹貳叁肆伍陸柒捌玖拾佰仟\\s]{1,10}[章節(jié)回集卷])(.*)
用法
+ (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 : @"書籍內(nèi)容為空或者書籍格式錯(cuò)誤"}]);
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 {
// 當(dāng)前標(biāo)題在全文中的位置
NSRange currentRange = NSMakeRange(0, 0);
// 當(dāng)前章節(jié)編號(hào)
NSInteger chapterIndex = 1;
// 循環(huán)處理章節(jié)
for (NSInteger i = 0; i < matches.count; i++) {
@autoreleasepool { // 自動(dòng)釋放池保證瞬時(shí)內(nèi)存不會(huì)過高
NSTextCheckingResult *result = matches[i];
// 下一個(gè)標(biāo)題在全文中的位置
NSRange resultRange = result.range;
// 截取兩個(gè)標(biāo)題之間內(nèi)容為當(dāng)前章節(jié)內(nèi)容
NSString *chapterContent = [content substringWithRange:NSMakeRange(currentRange.location + currentRange.length, resultRange.location - currentRange.location - currentRange.length)];
if (!TJIsEmptyObject(chapterContent) && resultRange.length <= 70) {
// 章節(jié)內(nèi)容不為空并且章節(jié)標(biāo)題長(zhǎng)度不超過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);
}
}
/// 處理章節(jié)內(nèi)容
/// @param content 內(nèi)容
+ (NSString *)resetContent:(NSString *)content {
if (!content || content.length == 0) {
return @"";
}
// 替換單換行
content = [content stringByReplacingOccurrencesOfString:@"r" withString:@""];
// 替換換行和多個(gè)換行(換行加空格)
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]];
// 章節(jié)開頭添加空格
content = [@" " stringByAppendingString:content];
return content;
}