【问题标题】:Split english text into senteces(multiple lines)将英文文本拆分成句子(多行)
【发布时间】:2018-06-09 11:47:43
【问题描述】:

我想知道一种将文本分成句子的有效方法。 句子由点+空格分隔

示例文本

 The quick brown fox jumps 
 over the lazy dog. I love eating toasted cheese and tuna sandwiches.

我的算法是这样工作的

Read first line from text file to string
Find what is needed
Write to file

但是,有时半个句子可能会出现在即将到来的行中。

所以我想知道解决这个问题的最佳方法是什么

是的,一个尝试过的谷歌搜索“跨多行搜索”,我不想使用正则表达式

最初我的想法是检查第一行是否以.+ space 结尾,如果没有,则抓取另一行并搜索它。但我有一种感觉,我错过了一些东西。

编辑:抱歉忘了说我是用 C++ 做的

【问题讨论】:

  • BreakIterator 可能会有所帮助? " 句子边界分析允许选择正确解释数字和缩写中的句点,以及尾随标点符号,如引号和括号。"
  • 你最初的想法有什么问题?那应该可以。
  • 不要逐行阅读,单独阅读每个字符并吃回车\r和换行\n。为您当前的工作“堆栈”保留一个 std::string 并在您看到句点(或 eof)时弹出堆栈。
  • 你不能将整个文本加载到内存中,然后搜索'.',后跟一个空格吗?
  • 您确定该行以.+space 结尾而不是.+newline 结尾吗?我会首先阅读单词stream >> word,然后检查每个单词的最后一个位置是否为'.'。这样>> 将处理空格字符以外的空格。

标签: c++ string text


【解决方案1】:

您可以使用累加器之类的东西。

1. Read line
2. Check the last symbols in this line.
3. If last symbols are dot or dot+space
 3.1 Split it and write all strings to output 
 3.2 GOTO 1
ELSE 
  3.3 split the line, write length-1 strings to output
  3.4 Keep last piece in some variable and append next readed line to it.

希望我的想法很清楚。

【讨论】:

    【解决方案2】:

    这是我解决这个问题的方法

    void to_sentences()
    {
        // Do not skip whitespaces
        std::cin >> std::noskipws;
    
        char c;
        // Loop until there is no input
        while (std::cin >> c) {
            // Skip new lines
            if (c == '\n')
                continue;
    
            // Output the character
            std::cout << c;
    
            // check if there is a dot folowed by space
            // if there add new line
            if (c == '.') {
                std::cin >> c;
                if (c == ' ')
                    std::cout << endl;
            }
        }
    
        // Reset skip whitespaces
        std::cin >> std::skipws;
    }
    

    你可以看一下cmets,看看有没有不清楚的地方。

    【讨论】:

      【解决方案3】:

      您可以使用std::getline(),与自定义分隔符'。'

      #include <sstream>
      #include <string>
      #include <vector>
      
      auto split_to_sentences(std::string inp)
      {
          std::istringstream ss(inp); // make a stream using the string
          std::vector< std::string > sentences; // return value
      
          while(true) {
              std::string this_sentence;
      
              std::getline(ss, this_sentence, '.');
              if (this_sentence != "") 
                  sentences.push_back(std::move(this_sentence));
              else 
                  return sentences;
          }
      }
      

      请注意,如果您将输入文本作为,则可以跳过std::stringstream 步骤,直接将流提供给std::getline,代替ss

      std::move 的使用不是必需的,但可以通过防止复制和删除std::string 的动态部分(在堆上)来提高性能。

      【讨论】:

      • 在我看来,这种方法的问题在于它不能处理新行。所以我认为你需要找到一种方法来处理它。
      猜你喜欢
      • 2017-04-18
      • 2011-11-03
      • 2019-08-27
      • 2013-04-28
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      • 2015-02-11
      相关资源
      最近更新 更多