我需要将文本文档/字符串中的每个句子都放到数组中。
问题在于如何处理标题,标题等文本部分,这些部分不是句子的一部分,但不以句号结尾“。”来检测。 无法检测到这些将导致他们被困在下一句话的前面(如果我使用“。”来区分句子),这是我不可能发生的。
最初我打算使用:
contentRefined = content.Replace(" \n", ". ");
我认为会删除所有空行和换行符,并在标题的末尾放置句点以便检测并将其视为句子,这将导致“。”但我可以再次替换它们没有。
但是没有工作它只是留下了完整的空行,只是在空行的开头放了一个“。”......以及每个段落开头的“。”
我现在尝试过:
contentRefined = Regex.Replace(content, @"^\s+$[\r\n]*", "", RegexOptions.Multiline);
完全删除完整的空行,但不会让我更接近在标题的末尾添加句点。
我需要将句子和标题/标题放在一个数组中,我不确定是否有一种方法可以做到这一点,而不必将字符串拆分为“。”
编辑:显示我如何从文件中获取测试的完整当前代码
public void sentenceSplit()
{
content = File.ReadAllText(@"I:\Project\TLDR\Test Text.txt");
contentRefined = Regex.Replace(content, @"^\s+$[\r\n]*", "", RegexOptions.Multiline);
//contentRefined = content.Replace("\n", ". ");
}
答案 0 :(得分:0)
我假设'标题'和'标题'在他们自己的行上并且不会在一段时间内结束。
如果是这种情况,那么这可能对您有用:
var filePath = @"C:\Temp\temp.txt";
var sentences = new List<string>();
using (TextReader reader = new StreamReader(filePath))
{
while (reader.Peek() >= 0)
{
var line = reader.ReadLine();
if (line.Trim().EndsWith("."))
{
line.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries)
.ToList()
.ForEach(l => sentences.Add(l.Trim() + "."));
}
}
}
// Output sentences to console
sentences.ForEach(Console.WriteLine);
<强>更新强>
使用File.ReadAllLines()
方法并在RichTextBox
中显示句子的另一种方法:
private void Form1_Load(object sender, EventArgs e)
{
var filePath = @"C:\Temp\temp.txt";
var sentences = File.ReadAllLines(filePath)
// Only select lines that end in a period
.Where(l => l.Trim().EndsWith("."))
// Split each line into sentences (one line may have many sentences)
.SelectMany(s => s.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries))
// Trim any whitespace off the ends of the sentence and add a period to the end
.Select(s => s.Trim() + ".")
// And finally cast it to a List (or you could do 'ToArray()')
.ToList();
// To show each sentence in the list on it's own line in the rtb:
richTextBox1.Text = string.Join("\n", sentences);
// Or to show them all, one after another:
richTextBox1.Text = string.Join(" ", sentences);
}
<强>更新强>
现在我觉得我明白你在问什么,这就是我要做的。首先,我会创建一些类来管理所有这些东西。如果您将文档分解为多个部分,则会出现类似的内容:
HEADER
第一句。第二句。段 句子中有一个数字,就像在这句话中所说:“5.00美元不会如此 就像以前一样“。
空栏目标题
多个段落的标题
第一句。段 第二句。第三段有一个数字,就像在这里一样 引用:“5.00美元并没有像以前那样”。
第一句。第二句。段落句子 三个有一个数字,就像在这句话中所说:“5.00美元并没有达到 它习惯于“。
第一句。第二句。段落句子 三个有一个数字,就像在这句话中所说:“5.00美元并没有达到 它习惯于“。
所以我会创建以下类。首先,一个代表一个'部分'。这是由标题和零到多段落定义的:
private class Section
{
public string Header { get; set; }
public List<Paragraph> Paragraphs { get; set; }
public Section()
{
Paragraphs = new List<Paragraph>();
}
}
然后我会定义一个段落,其中包含一个或多个句子:
private class Paragraph
{
public List<string> Sentences { get; set; }
public Paragraph()
{
Sentences = new List<string>();
}
}
现在我可以填充一个章节列表来代表文档:
var filePath = @"C:\Temp\temp.txt";
var sections = new List<Section>();
var currentSection = new Section();
var currentParagraph = new Paragraph();
using (TextReader reader = new StreamReader(filePath))
{
while (reader.Peek() >= 0)
{
var line = reader.ReadLine().Trim();
// Ignore blank lines
if (string.IsNullOrWhiteSpace(line)) continue;
if (line.EndsWith("."))
{
// This line is a paragraph, so add all the sentences
// it contains to the current paragraph
line.Split(new[] {". "}, StringSplitOptions.RemoveEmptyEntries)
.Select(l => l.Trim().EndsWith(".") ? l.Trim() : l.Trim() + ".")
.ToList()
.ForEach(l => currentParagraph.Sentences.Add(l));
// Now add this paragraph to the current section
currentSection.Paragraphs.Add(currentParagraph);
// And set it to a new paragraph for the next loop
currentParagraph = new Paragraph();
}
else if (line.Length > 0)
{
// This line is a header, so we're starting a new section.
// Add the current section to our list and create a
// a new one, setting this line as the header.
sections.Add(currentSection);
currentSection = new Section {Header = line};
}
}
// Finally, if the current section contains any data, add it to the list
if (currentSection.Header.Length > 0 || currentSection.Paragraphs.Any())
{
sections.Add(currentSection);
}
}
现在我们将整个文档放在一个部分列表中,我们知道它们包含的顺序,标题,段落和句子。作为如何分析它的一个例子,这里有一种方法可以将它写回RichTextBox
:
// We can build the document section by section
var documentText = new StringBuilder();
foreach (var section in sections)
{
// Here we can display headers and paragraphs in a custom way.
// For example, we can separate all sections with a blank line:
documentText.AppendLine();
// If there is a header, we can underline it
if (!string.IsNullOrWhiteSpace(section.Header))
{
documentText.AppendLine(section.Header);
documentText.AppendLine(new string('-', section.Header.Length));
}
// We can mark each paragraph with an arrow (--> )
foreach (var paragraph in section.Paragraphs)
{
documentText.Append("--> ");
// And write out each sentence, separated by a space
documentText.AppendLine(string.Join(" ", paragraph.Sentences));
}
}
// To make the underline approach above look
// half-way decent, we need a fixed-width font
richTextBox1.Font = new Font(FontFamily.GenericMonospace, 9);
// Now set the RichTextBox Text equal to the StringBuilder Text
richTextBox1.Text = documentText.ToString();