Created
November 5, 2017 16:13
-
-
Save chatton/c4328ed03eef086306ac052b89fb9797 to your computer and use it in GitHub Desktop.
Sample Eliza functionality using regex in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"regexp" | |
"strings" | |
"time" | |
) | |
type Response struct { | |
pattern *regexp.Regexp | |
possibleAnswers []string | |
} | |
func substituteWords(answer string, reflectionMap map[string]string) string { | |
allWords := strings.Split(answer, " ") // get slices of the words {"words", "in", "sentence"} | |
for index, word := range allWords { | |
if val, ok := reflectionMap[word]; ok { | |
allWords[index] = val // substitite the value | |
} | |
} | |
return strings.Join(allWords, " ") // join back into string "words in sentence" | |
} | |
func main() { | |
rand.Seed(time.Now().UnixNano()) | |
re := regexp.MustCompile("I like (.*)") // capture anything the after the phrase 'I like ' | |
// other possible patterns | |
// "I want (.*)", "I hate (.*)" etc. | |
answers := []string{"Why do you like %s?", "How long have you liked %s?"} // these be saved in a file and read in when you launch the program. | |
// ideally have a load of these, one for I Want, I like, I love etc. Can put them all in a file. Not coded into application. | |
likeResponse := Response{re, answers} // Responses could be read from files. | |
userInput := "I like you" // this would actually come from GET / POST request. | |
// we want to swap certain words so Eliza is actually talking about "you" and not just mimicing what was said, "I", | |
// a lot more useful swaps can be found here https://www.smallsurething.com/implementing-the-famous-eliza-chatbot-in-python/ | |
reflectionMap := map[string]string{ | |
"I": "you", | |
"was": "were", | |
"am": "are", | |
"you": "me", | |
// and plenty more | |
} | |
if likeResponse.pattern.MatchString(userInput) { | |
match := re.FindStringSubmatch(userInput) // the pattern matched, so let's look for all the text after I like. ie. everything in (.*) - (.*) means "anything", so this pattern will match any text the user entered. | |
topic := match[1] // 0 is the full string, 1 is first match. | |
topic = substituteWords(topic, reflectionMap) // instead of saying "Why do you like you" it maps to "Why do you like me" because of the reflection map. | |
index := rand.Intn(len(likeResponse.possibleAnswers)) // index of random possible answer | |
chosenResponse := likeResponse.possibleAnswers[index] // pick the answer | |
finalResponse := fmt.Sprintf(chosenResponse, topic) // sub the "topic" into the response - since the response has a %s for this purpose | |
fmt.Println(finalResponse) // we actually want to display this in the html page or template or something. | |
// The output will be "How long have you liked me?" or "Why do you like me?" | |
} else { | |
fmt.Println("I don't know what you said.") // there was no regex match so just say some default answer. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment