【问题标题】:Splitting sentences into strings across multiple lines将句子分成多行的字符串
【发布时间】:2017-11-21 20:39:39
【问题描述】:

我正在尝试阅读和处理文件中的文本。问题是我需要把它分成句子,想不出办法……

这是文本文件的示例:

I went to a shop. I bought a pack of sausages 

and some milk. Sadly I forgot about the potatoes. I'm on my way 

to the store

to buy potatoes.

如您所见,句子在结束之前可以跨越多行。我知道我应该使用正则表达式,但想不出办法...

【问题讨论】:

  • 确实很难确定你在问什么,但我认为你正在寻找的是:从字符串中删除所有换行符,然后用你需要的所有标点符号分割该字符串(@987654322 @、?! 等)

标签: c# regex string char


【解决方案1】:

我尝试将单独的行添加到一个实心字符串中,然后将其拆分为几个句子。

这是我尝试使用的方法:

static void Sakiniai (string fv, string skyrikliai)
    {
        char[] skyrikliaiSak = { '.', '!', '?' };

        string[] lines = File.ReadAllLines(fv, Encoding.GetEncoding(1257));
        string naujas = "";

        foreach (string line in lines)
        {
            naujas += line;
            naujas += " ";
        }

        string[] sakiniai = naujas.Split(skyrikliaiSak);
        for(int i = 0; i < sakiniai.Length; i++)
        {
            Console.WriteLine(sakiniai[i]);
        }

    }

告诉我有没有更好的方法来做到这一点。

【讨论】:

  • 首先,string naujas = File.ReadAllLines(fv, Encoding.GetEncoding(1257)).Join(" "); 另外,你认为什么更好?
【解决方案2】:

正如@maccettura 评论的那样,您可以尝试与此类似的东西。

string text = "...";
text = text.Replace(System.Environment.NewLine, " ").Replace("  ", " ");
        var sentences = text.Split(new char[] { '.', '!', '?' });
        foreach(string s in sentences)
        {
            Console.WriteLine(s);
        }

【讨论】:

    【解决方案3】:

    假设您将句子定义为输入的任何非空部分,由句点分隔。

    大概是这样的:

    (?<=^|\.)(.+?)(\.|$)
    

    关键可能是您应该使用RegexOptions.Singleline 选项,以便. 匹配任何字符(而不是除\n 之外的任何字符)。

    对上述模式的更详细解释:

    1. (?&lt;=^|\.)Zero-Width Positive Lookbehind Assertion ,它要求您的待匹配项位于输入的开头或前面有句点。匹配的时段本身不会成为匹配的一部分。
    2. (.+?) 是你的句子内容。 +? 运算符被称为惰性,因为它会尝试匹配尽可能短的输入部分。这是为了确保它不会从下一个模式部分抓取句号或下一个句子
    3. (\.|$) 将匹配句子终止符或输入的结尾。

    完整的工作示例:

    Regex r = new Regex(@"(?<=^|\.)(.+?)(\.|$)", RegexOptions.Singleline);
    String input = @"I went to a shop. I bought a pack of sausages
    and some milk. Sadly I forgot about the potatoes. I'm on my way
    to the store
    to buy potatoes.";
    foreach (var match in r.Matches(input))
    {
        string sentence = match.ToString();
    }
    

    【讨论】:

      【解决方案4】:

      我不知道你的文字可以有多长,所以以防万一我会逐句做。

      类似这样的:

              char[] periods = {'.', '!', '?'}; // or any other separator you may like
      
              string      line       = "";
              string      sentence   = "";
      
              using (StreamReader reader = new StreamReader ("filename.txt"))
              {
                  while ((line = reader.ReadLine()) != null)
                  {
                      if (line.IndexOfAny(periods)<0)
                      {
                          sentence += " " + line.Trim(); // increment sentence if there are no periods
      
                          // do whatever you want with the sentence
                          if (string.IsNullOrEmpty (sentence))
                              process(sentence);
      
                          continue;
                      }
      
                      // I'm using StringSplitOptions.None here so we handle lines ending with a period right
                      string[] sentences = line.Split(periods, StringSplitOptions.None);
      
                      for (int i = 0; i < sentences.Length; i++)
                      {
                          sentence += " " + line.Trim(); // increment sentence if there are no periods
      
                          // do whatever you want with the sentence
                          if (string.IsNullOrEmpty(sentence))
                              process(sentence);
      
                          // we don't want to clean on the last piece of sentence as it will continue on the next line
                          if (i < sentences.Length - 1)
                          {
                              sentence = ""; // clean for next sentence
                          }
                      }
      
                  }
      
                  // this step is only required if you might have the last line sentence ending without a period
                  // do whatever you want with the sentence
                  if (string.IsNullOrEmpty(sentence))
                      process(sentence);
      

      (请注意,如果您知道您只处理小文件,则不需要所有这些,您可以接受之前的建议)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-07
        • 1970-01-01
        • 1970-01-01
        • 2021-07-18
        • 2013-05-13
        相关资源
        最近更新 更多