2010-11-26 62 views
1

此刻我有一個非常簡單的自動回覆/聊天機器人。爲了讓它發揮更復雜的作用(如幫助機器人),它需要大量修改。我不是一個PHP程序員,但我想我知道一些研究後需要做什麼,我只是不完全理解php.net上的pregmatch和fopen等文章。我知道我可以下載一個現成的helpbot,但是我的學習曲線在哪裏?我也不急,我喜歡這些小小的挑戰。我在別處問過這個問題,那裏的知識知道什麼都不知道,或者根本不會被打擾 - 他們只是不停地告訴我下載預製的helpbot。PHP:我需要檢查用戶輸入字符串中的單詞並根據匹配輸出回覆

任何幫助將不勝感激,但請不要發回我的PHP手冊,因爲我已經嘗試過使用它。我需要一個新的方法。

我有一個表格供用戶輸入(最大長度)50個字符的文本問題。我認爲限制用戶可以輸入的字符數量將會是一個優勢,以便對字符串的操作變得更容易。 用戶提交問題後,需要將其傳遞給變量。

  1. 我想用一個單詞列表的字符串中的話,如果在文件中不存在的話已經廣告他們把它比在一個文件
  2. 然後。
  3. 確定某些關鍵詞(例如:誰;什麼;何處;何時;如何;爲什麼;哪個)以打破問題
  4. 確定任何名詞以進一步分解問題(名詞顯然將是一個相當大的名單,我將不得不手動創建)。
  5. 比較結果和答覆列表(我將手動創建另一個列表)。
  6. 輸出最佳匹配響應。

以下代碼是基本的,並且尚未檢查關鍵字組合的輸入字符串。我已經儘可能地評論了代碼,因爲我能理解它。

以下是我的responder002.php文件:

/*create the 'question' variable for the users text to be stored in:*/ 

$question=strtolower($_POST['question'])); 

/*begin creating the form*/ 
$ask='<br /><form action="responder002.php" method="POST">Question: <input type="text" name="question"> 
<input type="submit" value="Ask"></form>'; 
$answer='<h2>Answer</h2><br />'; 
/*if the $question variable is empty then ask for input*/ 
if (empty($question)) 
{ 
    print $ask; 

    exit; 
} 
/*otherwise ....*/ 
else 
{ 

    /*if the variable contains the following strings output to screen the matching response*/ 
    if ($question=="hello"||$question=="Hello"||$question=="hi"||$question=="Hi"||$question=="G'day"||$question=="hey") 
    { 
    $answerq="Hello how are you?"; 
    } 
    if ($question=="good"||$question=="good thanks") 
    { 
    $answerq="Im glad to hear you are good."; 
    } 
    if ($question=="fine"||$question=="fine thanks") { 
    $answerq="Im glad to hear you are fine."; 
    } 

    echo '<i>You asked me:</i> '.$question.' 
    <br /> 
    <i>I replied:'; 
    if (empty($answerq)) { 
    echo 'Sorry, I dont know the answer'; 
    } 
    echo '</i>'.$answerq.' '.$ask.; 
    exit; 
} 
echo '</table>'; 
$h->endpage(); 
?> 
+0

您需要編輯您的問題以確定清晰度。使用代碼`101010`按鈕,同時突出顯示這些代碼區域以使其正確顯示。 – Orbling 2010-11-26 21:36:05

+2

我覺得`/ *否則...... */else {`是我見過的最熱鬧的評論。 – meagar 2010-11-26 22:06:48

回答

1

嗯,這讓我想起了很多東西我做了很多很久以前,當我第一次開始編程。除了我開始問數學問題。編寫一個ELIZA類型的程序對於初學者來說是相當不錯的任務!

很明顯,你並不想寫一個屢獲殊榮的聊天界面,但我希望不會,因爲這是一個巨大的研究級別承諾。但我會嘗試給出幾個PHP示例,向您展示如何完成您希望採取的一些步驟以及您已採取的步驟。

長教程,振奮自己...

首先讓清理現有的代碼。

我從該文件的最後一行假定您正在使用某種HTML生成器,或試圖? $h->endpage();,因爲您經常使用exit;,所以它永遠不會被使用,其中終止該腳本出現的位置。除非你希望程序在該點結束,否則你不需要在if塊的末尾使用它。該程序將繼續在結束大括號}到下一個語句。

我看你在你的代碼中使用了echoprint。將變量寫入HTML頁面需要使用echo,但是有更好的方法可以執行將代碼和HTML分開的主要HTML頁面,因此您可以在兩者上進行更簡潔的工作。可以在頁面的任何位置使用開始和結束您的PHP頁面(<?php ?>)的標籤來「插入」和「分離」代碼。括號內,PHP,外部,HTML。

例如。

<?php 
// This is my PHP program 

// read the question variable from the Form data 
// the form was "post"ed, so we check $_POST 
// $_POST is an array (a list) of all the variables sent by the form 

$question = strtolower($_POST['question']); 

if (empty($question)) { 
    // no question, close PHP and start HTML, show the form 
?> 
<form action="responder002.php" method="POST"> 
    Question: <input type="text" name="question"> <input type="submit" value="Ask"> 
</form> 
<?php 
// back in PHP, if the question was not empty deal with the question 
} else { 
    // try and find an answer 
    if ($question == 'hello' || $question == 'hi') { 
    // hello-type question found 
    $answerp = "Hello, how are you?"; 
    } else if ($question == "fine" || $question == "fine thanks") { 
    // or a fine-type question 
    $answerq = "I am glad to hear you are fine."; 
    } else { 
    // "else" on its own, no question identified so we do not know 
    $answerp = "Sorry, I do not know the answer."; 
    } 

    // close PHP and display the answer 
    // note: opening and closing PHP briefly where we want a variable 
    //  using "echo" to output the variable contents 
?> 
<h2>Answer</h2> 

<p><i>You asked me:</i> <?php echo $question; ?></p> 
<p><i>I replied:</i> <?php echo $answerp; ?></p> 
<?php 
    // close the else opening bracket from above 
} 
// and we are done, close PHP 
?> 

一旦我們採取一個問題,回答這個基本方法,那麼我們可以繼續使其更充實。

你說你想存儲已經看到的單詞列表,並在新單詞出現時不斷添加。大概是這樣你可以手動查看正在提問的內容並寫出新的答案;還是你有另一個動機?

但是,如果您正在檢查數據並將其添加到數據庫中,則會存儲數據。如果你可以決定一個方法,或者數據是複雜的,你可以使用一個文本文件來存儲數據,大多數程序員會喜歡一個合適的數據庫系統,其中包含很多字段的記錄可以很容易地存儲。

現在讓我們假設你想使用文本文件。

步驟階段是決定如何存儲單詞,我的建議是保持簡單,每行一個單詞。

考慮到我們希望每行一個字,可能有許多讀取文件的方法,如果使用file()命令,可能是最方便和最簡單的方法。

$words = file("words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 

該命令在全體words.txt讀取,跳過任何空行和不存儲任何的行結尾(在一個文件中的每一行與一個新行字符或字符結束的,傳遞忽略新行選項的函數告訴PHP不保留這些。

$words現在是文件中的每一行的陣列,在他們在文件中出現的順序列表。

要檢查一個詞已經在一個文件中,我們可以使用in_array()函數,我們想知道我們正在檢查的單詞ing不在文件中。因此,我們可以說:

if (!in_array($currentWord, $words)) { 
    // add $currentWord to file 
} 

!字符意味着。那麼我們如何將這個單詞添加到文件中呢?那麼有另一個函數file_put_contents()(如果你使用的是比v5早的PHP版本,那麼這個函數不存在,告訴我,我會告訴你更復雜的方法)。 file_put_contents()要求我們在每個單詞之後放置換行符以結束行,因此我們將"\n"連接到每個單詞。

if (!in_array($currentWord, $words)) { 
    file_put_contents("words.txt", $currentWord . "\n", FILE_APPEND | LOCK_EX); 
} 

的標誌FILE_APPENDLOCK_EX告訴函數追加到文件的末尾,而不是重新從頭文件,並完全鎖定文件,而這樣做的,所以沒有人能寫文件而我們正在這樣做。

現在這一切都很好,一個字,$currentWord,但我們如何通過問題中的每個單詞?

第一步是將問題分解爲單詞。有幾種方法可以做到這一點,但爲此目的的簡單命令是explode()

explode()獲取一行或一段文本,並使用您指定的分隔符將其分割爲單個部分的列表(數組)。

$questionWords = explode(" ", $question); 

假設每個單詞用空格分隔,這將返回一個單詞數組。 explode()是一個簡單的功能,可以在每個空間分割,所以如果你有兩個空格在一起,它會把它分割開來,並說你在空格之間有一個空的字符串。 explode("-", "hello--world")(對於空格使用破折號)將列出例如('hello', '', 'world'),因爲雙破折號。爲了擺脫空的「單詞」,我們可以在爆炸中放置一個過濾器,以便刪除空的條目。

$questionWords = array_filter(explode(" ", $question)); 

現在,我們有我們的疑問詞的列表,我們怎麼把它與新詞的詞文件和存儲的閱讀起來呢?用循環。

$words = file("words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 

$questionWords = array_filter(explode(" ", $question)); 

foreach ($questionWords as $currentWord) { 
    if (!in_array($currentWord, $words)) { 
     file_put_contents("words.txt", $currentWord . "\n", FILE_APPEND | LOCK_EX); 
    } 
} 

foreach循環通過每個字在$questionWords通過括號之間的代碼的可變$currentWord每段時間設定。

這將工作,但效率非常低,因爲文件必須打開,寫入並關閉每個新單詞。建立一個新單詞清單並一次添加它們會更好。要做到這一點,我們創建一個空白的數組(列表)的新單詞,並添加新的單詞,當我們找到他們。

$words = file("words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 

$questionWords = array_filter(explode(" ", $question)); 

$newWords = array(); 
foreach ($questionWords as $currentWord) { 
    if (!in_array($currentWord, $words)) { 
     // add new word to $newWords 
     $newWords[] = $currentWord; 
    } 
} 

// write all the new words at once 
file_put_contents("words.txt", implode("\n", $newWords), FILE_APPEND | LOCK_EX); 

的新詞都通過採取$newWords列表和做的explode(),打破了行中各個單詞下跌相反,一次性加入,我們implode()在一個單件的單詞列表文字,每個單詞用換行符"\n"分隔。

我認爲這足以吸引眼下,仔細閱讀,熟悉這些概念並讓我知道你是否想繼續下去。

相關問題