更简单的寻找句子的方法是一个大字符串

本文关键字:一个 字符串 寻找 句子 方法 更简单 | 更新日期: 2023-09-27 18:12:38

我需要做的是将一长串文本解析成句子。句子是通过寻找终结符来分离的。终止符包括'。和?'和':'以及省略号("…")。

我能不能说

if (char is terminator) 
{ 
    // do this 
}

用干净的方式代替

if (char == '.' || char == '?' || char == etc etc etc etc ) 

我确实想过做一个终止符数组,然后做

if (ArrayofTerminators.Contains<char>('thechar'))
{
    // do that 
} 

但这看起来也很傻?

*编辑谢谢。这么多好评,真难选。无论如何,我决定使用UnhandledException的答案,因为它简洁而优雅,这正是我真正想要的。

更简单的寻找句子的方法是一个大字符串

如果切片为分隔字符串为您工作- String.Split支持分隔符数组(http://msdn.microsoft.com/en-us/library/b873y76a.aspx)

var sentences = "A?bcd。Foo !"Split(new char[] {'.','?', '!'});

如果省略号由单独的点表示,则split将不起作用。

如果你需要检查分隔符,只需要找到句子边界-考虑使用HashSet (http://msdn.microsoft.com/en-us/library/bb359438.aspx)的分隔符,而不是数组,如果你有很多字符的"在分隔符数组"检查

假设您只担心8位(或更少)的字符集,您可以很容易地使用布尔值数组。将终止符设置为true,其他所有内容设置为false。然后测试终止符变成:

if (terminators[char])
{
   // do this
}

您可以对较大的字符集执行相同的操作,但是对于较大的字符(例如,超过16位),它开始使用许多更多的内存。

字符串。如果你只需要在角色上进行分裂,那么分裂是很好的选择。如果需要更深入的内容,可以考虑使用正则表达式http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/b20b6bf7-fa5e-4c55-8e9d-e69762f178b0/

的regex.Split()。

这样您就可以捕获一些极端情况,例如:I can't wait until Jan. is here.中jan不是句尾

所有的分割都缺少标点符号。他们不工作。

获得句子的一个选项,它迭代字符。

下面的代码说明了为什么迭代可以工作而分割不行:

        string text = "sentence one. sentence two? sentence three...";
        List<string> sentences = new List<string>();
        StringBuilder sb = new StringBuilder();
        bool termHit = false;
        foreach (char c in text)
        {
            sb.Append(c);
            if (c == '.' || c == '?')
            {
                termHit = true;     
            }
            else
            {
                if (termHit)
                {
                    termHit = false;
                    sentences.Add(sb.ToString());
                    sb = new StringBuilder();
                }
            }
        }
        if (sb.Length > 0)
        {
            sentences.Add(sb.ToString());   
        }
        Console.WriteLine("Parse:");
        foreach (string sentence in sentences)
        {
            Console.WriteLine(sentence);    
        }
        string[] splits = text.Split(new char[] {'.', '?'});
        Console.WriteLine("Split:");
        foreach (string sentence in splits)
        {
            Console.WriteLine(sentence);    
        }

输出:解析:

句子。

句子的两个吗?

句子三…

分裂:

句子1

两个

句子三

句子

同样,正如洛曼在你的问题下的评论中指出的那样。解析句子的问题比所有这些解决方案都复杂得多。例如,标点符号包含点。

char[] delimiters = new char[] { '.', '?' };
string[] sentences= text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);