Parse String命令

时间:2015-03-03 16:46:30

标签: c# vb.net algorithm voice-recognition

我尝试(它是一个实验)开发一个简单的应用程序,返回数据,给定语音命令(使用iOs Siri,或Android语音识别等)。 我想解析'它。

我使用这种方法,但我很确定它不正确。 假设用户说"给我2015年客户鸭子收入"

if InStr(mystring, "Revenue")>0 then
 sql = sql " SELECT revenue FROM mytable "
end if
if InStr(mystring, "Give me Revenue")>0 then
 sql = sql " SELECT revenue FROM mytable "
end if
... 
...
if InStr(mystring, "April")>0 then
 sql = sql " Where month=4 "
end if
if InStr(mystring, "from April")>0 then
 sql = sql " Where month>=4 "
end if
... 
...

这是一个好方法吗? 第二个问题:如何解析客户名称?客户可能是一百万......最好的方法是什么?

由于

3 个答案:

答案 0 :(得分:2)

首先让我们假设一些事情。根据评论“mystring是正确识别的字符串”,您不会询问有关命令的语音识别,只会询问用户名。

对于用户名,您可能需要计算VR机制和用户数据库之间的距离。 VR系统“听到”鸭子,查看所有用户的距离鸭子并采取最小的距离。 “查克”比“白金汉”更有可能成为竞争对手。 我认为您可能需要根据业务规则调整机制才能工作,但您已经可以在名称之间创建Levensthein distance概念验证。

我要在地毯下清除名字识别。你需要确定你的要求,而你的问题还不够准确。

现在关于语言的解析,我认为更简单的方法是创建Parsing Expression Grammar。它允许您定义语法,然后由生成器转换为代码。然后代码将能够解析遵循您期望的语法的文本。甚至还有一个用于C#的PEG库,您可以使用它来生成解析代码peg-sharp

PEG易于构建且易读。您可以使用PEG.js在线培训以构建您的第一个语法。您首先需要查看如何将句子转换为代码。让我们说

  • 给我2015年鸭子收入
  • 2015年获取Duck的收入

应该是等效的命令,你会说你的系统应该将它转换为Operation(get),参数为customer(Duck),dataFields(收入)和{{1 (2015年)。这可以翻译成以下语法:

timeWindow

当然这个样本语法非常幼稚;句子结构不能考虑变化,但这是找到句子解析的一般规则的问题:

  • 忽略空格和噪音(例如本例中的占有start = command command = "Give me " year:year " " dataFields:dataFields " for " customer:customer { return { "operation" : "get" , "customer": customer , "year": year , "dataFields": dataFields }; } / "Fetch " customer:customer "'s " dataFields:dataFields " in " year:year { return { "operation" : "get" , "customer": customer , "year": year , "dataFields": dataFields }; } dataFields "dataFields" = "revenue" year "year" = digits:[0-9]+ { return parseInt(digits.join(""), 10);} customer "customer" = letters:[a-zA-Z]+ {return letters.join("");} ,如果用户感到沮丧,则为咒骂:))
  • 创建规则,其中元素不依赖于顺序,但可以从句子中的任何位置选取
  • 扩展可能的's和命令

如果您在PEG.js上尝试它,您可以看到它能够将句子转换为JSON对象(使用peg-sharp,它将是您通过代码控制的行为的C#对象)

通过这个以及对句子中的变化进行一些规划,您应该能够创建第一种方法来满足您的需求

答案 1 :(得分:1)

如果我已经正确理解了你的问题,你想要的是什么(这只是伪代码,我现在无法测试代码):

Hashtable keywords = new Hashtable();
keywords.add("revenue", 1);
keywords.add("from", 1);
//Add more keywords
...
string[] words = mystring.ToLower().Split(' ');
foreach (string word in words)
{
    if (keywords[word] == 1)
    {
        //Do something based on keywords found
        //E.g. assigning delegates to invoke functions
        //or preparing an SQL string that you can then execute
        //(BEWARE OF SQL-INJECTION IF YOU USE STRINGS)
        //or simply making a big switch-case
    }
}

答案 2 :(得分:1)

您所描述的是一个相当复杂的自然语言处理问题。如果您可以使用外部API,那么请查看wit.ai(最近由facebook购买),这完全符合您的要求。您给出了几个应用程序期望的自然语言命令示例,然后您发送一个录音,然后它会返回一个JSON,其中包含它认为语音命令的意图。