文章目录
- 清理空格
- 段落拼接
- 去除空行
- 按键事件
txt阅读器系列:
- 需求分析和文件读写
- 目录提取类💎列表控件与目录💎快捷键翻页
- 字体控件绑定💎前景/背景颜色
- 书籍管理系统💎用树形图管理书籍
- 语音播放💎播放进度显示💎快进快退💎语速音量
- 文本清理的布局💎段落合并
清理空格
接下来实现清理空格、段落拼接、去处空行这三个功能,这里的清理空格表示去除首尾空格,为了实现这个功能,需要先将字符串分割为字符串列表,然后将列表中每个字符串的首尾空格去掉,一行代码就可以实现
var ch = "\r\n";
if (fmtCheckBoxes[0].IsChecked == true)
doc = String.Join(ch, doc.Split(ch)
.Select(L => L.Trim())
.ToArray());
段落拼接
然后考虑段落拼接,只需找到字符串中的所有换行的位置,如果这些换行符前面,并不是允许换行的终止符号,则删除这个地方的换行。而文字中经常出现的终止符号基本都是标点符号,故其代码可写为
private List<string> mergePara(List<string> sLst, string LF="\r\n")
{
const string TERMINATOR = ",.!?,。!?”";
int i = 0;
while (i < sLst.Count - 1)
{
if (!TERMINATOR.Contains(sLst[i].Last()))
{
sLst[i] = sLst[i] + sLst[i + 1];
sLst.RemoveAt(i + 1);
continue;
}
i++;
}
return sLst;
}
其核心代码为while
循环的第一个判断语句,若第i
行的最后一个字符不属于终止符,则将第i+1
行合并到第i
行后,删除第i+1
行,然后重复执行此项操作。否则的花,跳到下一行。
去除空行
最后考虑去除空行,这一条也比较简单,无非把多余一个的\r\n
替换为\r\n
即可,最直观的写法是
if (fmtCheckBoxes[2].IsChecked == true)
while (doc.Contains("\r\n\r\n"))
doc = doc.Replace("\r\n\r\n", "\r\n");
但这么些可能会在空格较多的情况下,执行更多次的循环,并不划算,故而可以展开来写
private List<string> deleteDoubleLine(List<string> sLst)
{
int i = 0;
while (i < sLst.Count - 1)
{
if (sLst[i] == "" & sLst[i+1]=="" )
{
sLst.RemoveAt(i + 1);
continue;
}
i++;
}
return sLst;
}
其含义非常简单,与mergePara
的逻辑基本是相同的,只不过在判断时,要求当前行和下一行都为空行,则删除下一行。
按键事件
这些功能都实现了之后,就可以写交互逻辑了,为文本清洗
中的执行
按钮添加btnFMT_Click
事件,其内容为
private void btnFMT_Click(object sender, RoutedEventArgs e)
{
var ch = "\r\n";
List<string> sLst = doc.Split(ch).ToList();
if (fmtCheckBoxes[0].IsChecked == true)
sLst = sLst.Select(L => L.Trim()).ToList();
if (fmtCheckBoxes[1].IsChecked == true)
sLst = mergePara(sLst, ch);
if (fmtCheckBoxes[2].IsChecked == true)
sLst = deleteDoubleLine(sLst);
doc = string.Join(ch, sLst);
}
结合txtReader
的其他功能,这个业务流程中有两个bug
,都和目录有关,其一是目录结尾并没有标点符号,也就是说,上面这些文本的清洗方式,会导致目录无法识别。所以需要对目录进行保护,在mergePara
刚进入while
循环时加上一个判断
if (catalog.Contains(sLst[i]))
{
i++;
continue;
}
其二则是重新生成目录时,在清空目录时会改变ListBox
的SelectedIndex
,从而触发事件,但此时doc
文件已经发生了变化,所以会报错。故而更改btnCatalog_Click
中的内容,在Clear
前后取消并重新注册事件。
lvCatalog.SelectionChanged -= lvCatalog_SelectionChanged;
lvCatalog.Items.Clear();
lvCatalog.SelectionChanged += lvCatalog_SelectionChanged;
其最后效果如下