2010-02-04 36 views
0

這個SAPI語法捕捉單詞的名字是一個句子的中間。如何在微軟SAPI的句子中間抓住單詞?

<GRAMMAR LANGID="409"> 
    <RULE NAME="SOUNDLOG" TOPLEVEL="ACTIVE"> 
     <OPT> 
      <DICTATION MAX="INF"/> 
     </OPT> 
     <L> 
      <P>name</P> 
     </L> 
     <OPT> 
      <DICTATION MAX="INF"/> 
     </OPT> 
    </RULE> 
</GRAMMAR> 

所以,如果我說「我的名字是安德烈」,那麼「名字」一詞就被確定了。 有沒有更好的方法來做到這一點?

回答

2

當您獲得識別時,與識別關聯的SPPHRASE數據包含子識別和屬性數據以及它們在識別中出現的位置。

因此,如果您有'名稱'的規則或屬性標籤,您可以找到與'名稱'相關的字詞。

例如,假設你的語法

<GRAMMAR LANGID="409"> 
    <RULE NAME="SOUNDLOG" TOPLEVEL="ACTIVE"> 
     <OPT> 
      <DICTATION MAX="INF"/> 
     </OPT> 
     <L> 
      <P>name</P> 
     </L> 
     <OPT> 
      <DICTATION MAX="INF"/> 
     </OPT> 
    </RULE> 
</GRAMMAR> 

,如果你將其更改爲

<GRAMMAR LANGID="409"> 
    <RULE NAME="SOUNDLOG" TOPLEVEL="ACTIVE"> 
     <OPT> 
      <DICTATION MAX="INF"/> 
     </OPT> 
     <L PROPNAME='name'> 
      <P VAL='name'>name</P> 
     </L> 
     <OPT> 
      <DICTATION MAX="INF"/> 
     </OPT> 
    </RULE> 
</GRAMMAR> 

,你可以找到對應於 '名' 的話是這樣的:

HRESULT OnRecognition(ISpRecoResult* pResult) 
{ 
    SPPHRASE *pPhrase; 
    HRESULT hr = pResult->GetPhrase(&pPhrase); 
    if (SUCCEEDED(hr)) 
    { 
     const SPPHRASEPROPERTY pProp = FindProperty(pPhrase->pProperty, L"name"); 
     if (pRule) 
     { 
      LPWSTR text(NULL); 
      hr = pResult->GetText(pProp->ulFirstElement, pProp->ulCountOfElements, TRUE, &text, NULL); 
      if (SUCCEEDED(hr)) 
      { 
       // do something with text 
       ::CoTaskMemFree(text); 
      } 
     } 
    } 
    return hr; 
} 
const SPPHRASEPROPERTY* FindProperty(const SPPHRASEPROPERTY* pProp, LPCWSTR what) const 
{ 
    while (pProp!=NULL) 
    { 
     if (pProp->pFirstChild != NULL) 
     { 
      const SPPHRASEPROPERTY* pFoundProp = FindRule(pProp->pFirstChild, what); 
      if (pFoundProp) 
      { 
       return pFoundProp; 
      } 
     } 
     if (pProp->pszName != NULL && wcsstr(pProp->pszName, what) != NULL) 
     { 
      return pProp; 
     } 
     pProp = pProp->pNextSibling; 
    } 
    return NULL; 
} 

該代碼專門針對該屬性所涵蓋的文本。但是,最好使用val屬性來標識項目,而不將其代碼明確地綁定到語法。這使您可以在不更改代碼的情況下調整語法(或添加等效值)。要使用這些值,只需在獲取屬性(而不是使用ISpPhrase :: GetText)後使用SPPHRASEPROPERTY.pszValue或vValue字段即可。

+0

請參閱我編輯的問題:) – 2010-02-06 16:08:52

+0

請參閱編輯答案。 :) – 2010-02-07 19:18:49

+0

你有在C#代碼? – 2010-02-08 14:43:48