解析字符串命令
Parse String command
我正在尝试(这是一个实验)开发一个简单的应用程序 return 数据,给定语音命令(使用 iOs Siri,或 Android 语音识别等) .
我想'parse'了。
我正在使用这种方法,但我很确定它不正确。
假设用户说 "Give me 2015 Revenue of customer Duck"
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
...
...
这是一个好方法吗?
第二个问题:如何解析客户名称?客户可能有 100 万……最好的方法是什么?
谢谢
如果我没有正确理解你的问题,你想要的是这样的(这只是伪代码,我现在无法测试代码):
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
}
}
首先让我们假设一些事情。根据评论 "mystring is the string correctly recognized" 你不是在询问命令的语音识别,只是在询问用户名。
对于用户名,您可能需要计算 VR 机制所理解的内容与您的用户数据库之间的距离。 VR系统"hears"Duck,查找所有用户Duck的距离,取最小的距离。 "Chuck" 比 "Buckingham" 更有可能成为竞争者。
我认为您可能需要调整机制才能根据您的业务规则工作,但您已经可以使用名称之间的 Levensthein distance 创建概念证明。
我将把名字识别扫到地毯下。您需要确定您的要求,而您的问题还不够精确,无法做到这一点。
现在关于语言的解析,我认为更简单的方法是创建一个 Parsing Expression Grammar. It lets you define a grammar that is then turned into code by a generator. The code will then be able to parse the text obeying the grammar you are expecting. There is even a PEG library for C# that you can use to generate the parsing code, peg-sharp
PEG 易于构建且可读性强。您可以使用 PEG.js 在线训练来构建您的第一个语法。您首先需要了解如何将句子翻译成代码。比方说
- 给我 2015 年 Duck 的收入
- 2015 年 Fetch Duck 的收入
应该是等效的命令,您会说您的系统应该将其转换为带有参数 customer
(Duck)、dataFields
(收入)和 timeWindow
(2015 年)。这可以翻译成以下语法:
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
,或者如果用户感到沮丧则咒骂 :))
- 创建元素不依赖于顺序但可以从句子中的任何位置选取的规则
- 扩展可能
dataFields
和命令
如果你在 PEG.js 上尝试它,你会发现它能够将句子翻译成 JSON 对象(使用 peg-sharp 将是一个 C# 对象,你可以通过它控制行为代码)
有了这个以及对句子中的变化进行一些规划,您应该能够创建满足您需要的第一种方法
你描述的是一个比较复杂的自然语言处理问题。如果您可以使用外部 API,请查看 wit.ai(最近由 facebook 购买),这正是您想要的。你给它几个你的应用程序期望的自然语言命令的例子,然后你给它发送一个录音,它 returns 你一个 JSON 它认为语音命令的意图是什么。
我正在尝试(这是一个实验)开发一个简单的应用程序 return 数据,给定语音命令(使用 iOs Siri,或 Android 语音识别等) . 我想'parse'了。
我正在使用这种方法,但我很确定它不正确。 假设用户说 "Give me 2015 Revenue of customer Duck"
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
...
...
这是一个好方法吗? 第二个问题:如何解析客户名称?客户可能有 100 万……最好的方法是什么?
谢谢
如果我没有正确理解你的问题,你想要的是这样的(这只是伪代码,我现在无法测试代码):
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
}
}
首先让我们假设一些事情。根据评论 "mystring is the string correctly recognized" 你不是在询问命令的语音识别,只是在询问用户名。
对于用户名,您可能需要计算 VR 机制所理解的内容与您的用户数据库之间的距离。 VR系统"hears"Duck,查找所有用户Duck的距离,取最小的距离。 "Chuck" 比 "Buckingham" 更有可能成为竞争者。 我认为您可能需要调整机制才能根据您的业务规则工作,但您已经可以使用名称之间的 Levensthein distance 创建概念证明。
我将把名字识别扫到地毯下。您需要确定您的要求,而您的问题还不够精确,无法做到这一点。
现在关于语言的解析,我认为更简单的方法是创建一个 Parsing Expression Grammar. It lets you define a grammar that is then turned into code by a generator. The code will then be able to parse the text obeying the grammar you are expecting. There is even a PEG library for C# that you can use to generate the parsing code, peg-sharp
PEG 易于构建且可读性强。您可以使用 PEG.js 在线训练来构建您的第一个语法。您首先需要了解如何将句子翻译成代码。比方说
- 给我 2015 年 Duck 的收入
- 2015 年 Fetch Duck 的收入
应该是等效的命令,您会说您的系统应该将其转换为带有参数 customer
(Duck)、dataFields
(收入)和 timeWindow
(2015 年)。这可以翻译成以下语法:
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
,或者如果用户感到沮丧则咒骂 :)) - 创建元素不依赖于顺序但可以从句子中的任何位置选取的规则
- 扩展可能
dataFields
和命令
如果你在 PEG.js 上尝试它,你会发现它能够将句子翻译成 JSON 对象(使用 peg-sharp 将是一个 C# 对象,你可以通过它控制行为代码)
有了这个以及对句子中的变化进行一些规划,您应该能够创建满足您需要的第一种方法
你描述的是一个比较复杂的自然语言处理问题。如果您可以使用外部 API,请查看 wit.ai(最近由 facebook 购买),这正是您想要的。你给它几个你的应用程序期望的自然语言命令的例子,然后你给它发送一个录音,它 returns 你一个 JSON 它认为语音命令的意图是什么。