我在程序中使用语音识别,为了比写出每一个可能的单词组合来执行某个命令更容易,我使用.Contains函数来挑选某些关键字。实例
private void SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
{
string speech = e.Result.Text;
if (speech.Contains("next") && speech.Contains("date"))
{
MessageBox.Show(speech + "nThe date will be the 11th");
}
else if (speech.Contains("date"))
{
MessageBox.Show(speech + "nThe date is the 10th");
}
}
正如你所看到的,如果语音在某种程度上被识别,它会显示一个文本框,说明它假设的内容,然后是日期。然而,当我看到文本框中显示的演讲时,它会说"下一次更新"之类的话。因此,该程序在另一个单词中寻找一个单词,即"更新"中的"日期"。我不希望这种情况发生,否则它就不会那么准确,如何使.Contains方法自己挑出单词,而不查看其他单词的内部?感谢
替代解决方案,拆分所有空格并检查关键字
string speech_text = e.Result.Text;
string[] speech = speech_text.Split();
if (speech.Contains("next") && speech.Contains("date"))
{
MessageBox.Show(speech_text + "nThe date will be the 11th");
}
else if (speech.Contains("date"))
{
MessageBox.Show(speech_text + "nThe date is the 10th");
}
您可以使用String.Split
来获取所有单词。然后使用Ènumerable.Contains
检查其中一个单词是否匹配。以下是一个不区分大小写的比较示例:
char[] wordSeparators = new[] { 'n', 't', ',', '.', '!', '?', ';', ':', ' ', '-', '/', '\', '[', ']', '(', ')', '<', '>', '@', '"', ''' };
string[] words = e.Result.Text.Split(wordSeparators, StringSplitOptions.RemoveEmptyEntries);
bool containsNext = words.Contains("next", StringComparer.CurrentCultureIgnoreCase);
bool containsDate = words.Contains("date", StringComparer.CurrentCultureIgnoreCase);
if ( containsNext && containsDate )
{
MessageBox.Show(e.Result.Text + "nThe date will be the 11th");
}
else if ( containsDate )
{
MessageBox.Show(e.Result.Text + "nThe date is the 10th");
}
作为扩展方法可能很方便:
static readonly char[] wordSeparators = { 'n', 't', ',', '.', '!', '?', ';', ':', ' ', '-', '/', '\', '[', ']', '(', ')', '<', '>', '@', '"', ''' };
public static bool ContainsWord(this string input, string word, StringComparer comparer = null)
{
if (input == null || word == null) throw new ArgumentNullException("input and word must be specified");
if (input.Length < word.Length) return false;
if (comparer == null) comparer = StringComparer.CurrentCultureIgnoreCase;
return input.Split(wordSeparators, StringSplitOptions.RemoveEmptyEntries).Contains(word, comparer);
}
现在你可以用这种方式在任何地方使用它:
bool containsNext = e.Result.Text.ContainsWord("next");
bool containsDate = e.Result.Text.ContainsWord("date");
使用正则表达式,可以强制单词被"单词边界"包围。
private void SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
{
string speech = e.Result.Text;
bool matchesDate = Regex.IsMatch(speech, @"bdateb");
if (Regex.IsMatch(speech, @"bnextb") && matchesDate)
{
MessageBox.Show(speech + "nThe date will be the 11th");
}
else if (matchesDate)
{
MessageBox.Show(speech + "nThe date is the 10th");
}
}
这将匹配"下一个日期",而不是"下一次更新"。
使用正则表达式会更好。
if (Regex.IsMatch(speech, @"bnextb") && Regex.IsMatch(speech, @"bdateb"))
{
MessageBox.Show(speech + "nThe date will be the 11th");
}
else if (Regex.IsMatch(speech, @"bdateb"))
{
MessageBox.Show(speech + "nThe date is the 10th");
}