在c#中用引号分割句子

时间:2015-11-30 15:36:31

标签: c# algorithm

我正在为书籍制作处理系统,作为其中的一部分,我需要一个强大的算法来将文本分成句子。

直接的方法是根据角色的出现简单地分割文本。但是很多书都大量使用引号,这并没有给出正确的结果。考虑一下这句话:

'加油!'他喊道。他很不高兴。

将分成

  1. '加油!
  2. '他喊道。
  3. 他很不高兴。
  4. 虽然我们想要这个结果:

    1. '加油!'他喊道。
    2. 他很不高兴。
    3. 现在,我们可以检测到了。?!字符在引号内,并且永远不会在引用的文本中分割,但是检测引号内的内容并不是微不足道的。考虑一下这句话:

      '发生了什么事?'他问道。

      这需要我们检测一个quatation mark和一个用于其他目的的撇号之间的区别,例如“那个”,“69'ers'”,“他'n'Hers'”等等。

      我们无法控制使用何种引号。 Could be "quote", ‘quote’, 'quote', “quote”.撇号字符如"that's" or "that’s" ...如果差异在这里不容易看到,我很抱歉,但是使用了很多不同的引号字符。

      其中许多案件都是微不足道的,但我们也必须处理最坏情况下的scanerios,就像之前的例子一样。

      至少在大多数情况下,报价的开头是与报价结尾不同的字符。例如:

      '我们会在几个小时后回来。'

      所以,这给了我们一个非常可靠的迹象,表明报价至少何时开始。虽然,目前还不清楚哪个角色会结束引用。

      任何人都知道一个好的解决方案吗?

      编辑:我现有的代码,处理引用字符与使用的撇号不同的最简单的情况:

          public static List<string> splitSentences(string text)
          {
              List<string> sentences = new List<string>();
              StringBuilder sb = new StringBuilder();
              bool insideQuote = false;
              for (int i=0;i<text.Length;i++)
              {
                  char c = text[i];
      
                  //Handle quotes properly
                  if (isQuote(c))
                      insideQuote = !insideQuote;
                  sb.Append(c);
                  if ( !insideQuote && isSentenceDelimiter(c) )
                  {
                      string s = sb.ToString().Trim();
                      if (s.Length>0)
                          sentences.Add(s);
                      sb.Clear();
                      insideQuote = false;
                  }
              }
      
              if (sb.Length > 0)
              {
                  string s = sb.ToString().Trim();
                  if (s.Length > 0)
                      sentences.Add(s);
              }
      
              return sentences;
          }
      
      
          private static char[] splitter = new char[] { '.', '!', '?', '。', '!', '?', '\n', '\r' };
          private static bool isSentenceDelimiter(char c)
          {
              foreach (char d in splitter)
                  if (d.Equals(c))
                      return true;
              return false;
          }
      
          private static char[] quotechar = new char[] { '"', '“', '”' };
          private static bool isQuote(char c)
          {
              foreach (char d in quotechar)
                  if (d.Equals(c))
                      return true;
              return false;
          }
      

0 个答案:

没有答案