我需要做的是将大量文本解析成句子。通过寻找终结者来隔离句子。终结者包括'。'和'?'和':'和省略号(“......”)。
有没有办法可以说
if (char is terminator)
{
// do this
}
以干净的方式而不是
if (char == '.' || char == '?' || char == etc etc etc etc )
我确实想过做一个终结器数组并做
if (ArrayofTerminators.Contains<char>('thechar'))
{
// do that
}
但这似乎也很愚蠢?
*编辑谢谢。难以选择这么多好的回复。无论如何,我决定采用UnhandledException的答案,因为它紧凑而优雅,正是我真正想要的。
答案 0 :(得分:2)
如果切入分隔字符串适合您 - String.Split
支持分隔符数组(http://msdn.microsoft.com/en-us/library/b873y76a.aspx)
var sentenses =“A?bcd.Foo!”。Split(new char [] {'。','?','!'});
如果省略号由单独的点表示,则拆分将无效。
如果你需要检查分隔符并且只需找到句子边界 - 如果你有很多字符用于“在分隔符数组中”,请考虑使用HashSet
(http://msdn.microsoft.com/en-us/library/bb359438.aspx)分隔符而不是数组
答案 1 :(得分:1)
假设你只担心一个8位(或更少)的字符集,你可以很容易地做一个布尔数组。将终止符设置为true,将其他所有内容设置为false。然后测试终结器变为:
if (terminators[char])
{
// do this
}
对于较大的字符集,您可以执行相同的操作,但对于大字符(例如,超过16位),它开始使用 lot 更多内存。
答案 2 :(得分:1)
如果您只需要拆分字符,String.Split就很棒。如果您需要更深入的内容,请考虑使用regex.Split(),使用此处的正则表达式http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/b20b6bf7-fa5e-4c55-8e9d-e69762f178b0/
通过这种方式,您可以捕捉到一些极端情况:I can't wait until Jan. is here.
,其中Jan.不是句子的结尾。
答案 3 :(得分:1)
所有分裂都缺少惩罚。它们不起作用。
让句子迭代字符的一个选项。
此代码显示了迭代工作和拆分的原因:
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);
}
输出:
<强>解析:强>
第一句话。 句子二? 第三句......<强>分割强>
第一句 第二句话 第三句另外,正如洛曼在你提问的评论中指出的那样。解析句子的问题要比所有这些解决方案复杂得多。例如,标点符号包含点。
答案 4 :(得分:0)
char[] delimiters = new char[] { '.', '?' };
string[] sentences= text.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);