我在网上看小说时,习惯把它先全部下载到本地来看(一般自己写个蜘蛛程去抓)。貌似是为了防止把html页面中表格撑爆,许多小说每隔几十个字符固定换行,这样下载到本地的时候看起来就很不爽,因此我就写了个程序将这些换行的文本来合并一下。
基本原理如下:
- 通过trim函数去掉多余的空格
- 如果旧行是以标点符号结束,则认为是段落结束,需要加换行符,否则则去掉原来的换行符。
代码实现如下:
static
void Main(string[] args)
{
var lines = File.ReadAllLines(@"r:\1.txt",Encoding.Default);
File.WriteAllLines(@"r:\2.txt",JoinLine(lines));
}
static
string[] JoinLine(string[] lines)
{
var newLine = from line in lines
select
Regex.Replace(line.Trim(), @"(.+\W)$", m => m.Groups[1].Value + "\n");
return
string.Join("", newLine.ToArray()).Split('\n');
}
这个以标点符号是否为结束符来合并的算法没有什么大问题,但有一个地方无法解决,那就是"第一章 xxxxx"这样的标题栏实际上还是应该换行的,但上面的算法把它和下面的行合并了起来。因此我将其算法又改进了一下,添加了一个可以自己某些特殊行的条件检查,最终版本如下:
static
void Main(string[] args)
{
var lines = File.ReadAllLines(@"r:\1.txt",Encoding.Default);
File.WriteAllLines(@"r:\2.txt", JoinLine(lines, line => Regex.Match(line, "第.+?章").Success));
}
static
string[] JoinLine(string[] lines,Func<string,bool> exceptHanlder)
{
Func<string, string> GetNewLine = s => s + "\n";
var newLineQuery = from line in lines.Select(i => i.Trim())
let newLine = Regex.Replace(line, @"(.+\W)$", m => GetNewLine(m.Groups[1].Value))
select exceptHanlder(newLine) ? GetNewLine(newLine) : newLine;
return
string.Join("", newLineQuery.ToArray()).Split('\n');
}