如何停止字符串.Contains()从另一个单词中挑出一个单词.更好的解释如下



我在程序中使用语音识别,为了比写出每一个可能的单词组合来执行某个命令更容易,我使用.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");
        }

最新更新