Skip to content

Instantly share code, notes, and snippets.

@chatton
Created November 5, 2017 16:13
Show Gist options
  • Save chatton/c4328ed03eef086306ac052b89fb9797 to your computer and use it in GitHub Desktop.
Save chatton/c4328ed03eef086306ac052b89fb9797 to your computer and use it in GitHub Desktop.
Sample Eliza functionality using regex in Go
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