简体   繁体   中英

C# Detecting a word in user input textbox

Good evening!

I'm trying to achieve some sort of primitive AI. My Hobby Project basically contains two textboxes. One for input and one for output.

So let's say the user feels the urge to tell my AI his Name after a couple hours of flirting. He would type in "I am called 'Jack Black'"

How would I go about storing his name in a variable? (Or storing First Name and Last Name each in one variable)

Is there some sort of placeholder mechanic where I can store the name string after a set of predicted words? (like "I am called")

My guess:

switch (MyMessage)
        {
            case "Hi":
                BotSays("Hello!");
                break;
            case "I am called " + PLACEHOLDER:
                BotSays("Thats a pretty sick name!");
                user_firstName = PLACEHOLDER;
                break;
            default:
                BotSays("Sory me no understand");
                break;
        }  

I hope its understandable what my Question is since I probably cant find the right words to get usefull results on Google, Stack Overflow and Co.

Thank you

Hooboy. I'm not sure if you realize just how monumental of a task you've undertaken. My higher-level suggestion would be: Look up 'Eliza' and try writing a port of it in C#. It's a simple Chat-Bot that you could tweak from there if you're interested.

As for your specific question? I think what you're looking for are Regex'es. Take something like this:

string sampleText = "Hello, my name is Inigo Montoya";
Regex namePattern = new Regex(@"Hello, my name is (?<FirstName>\w+) (?<LastName>\w+)$");
Match match = namePattern.Match(sampleText);
string firstName = match.Groups["FirstName"].Value;
string lastName = match.Groups["LastName"].Value;

MessageBox.Show("He said his name was " + firstName + " " + lastName);

... Regexes are a really neat way of parsing strings in a dynamic way. In this case, it'll let you check whether the name matches that Regex - and if it does, it'll fill out the firstName and lastName variables for you.

Here's one way to do this, although I think regular expressions would make it much simpler. I just don't know RegEx very well.

First you could create a list of the "well known prefixes" to someone introducing themselves:

var stringsBeforeIntroduction = new List<string>
{
    "I am called ",
    "My name is ",
    "People call me ",
    "You can refer to me as "
};

And a list of known characters that would follow a name:

var charactersAfterName = new char[]
{
    ' ', ',', '.', '\n', ';', ':'
};

Then, you can search for the index of the first "introduction prefix" you find:

var firstPrefixFound =
    stringsBeforeIntroduction.FirstOrDefault(
        prefix => MyMessage.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) > -1);

Now, if firstPrefixFound is not null, then we found the prefix. Next we have to grab the name portion, which will be the rest of the string (or until we hit one of our charactersAfterName characters:

if (firstPrefixFound != null)
{
    // Calculate the indexes of the start and end of the name
    int prefixLength = firstPrefixFound.Length;
    int startName = MyMessage.IndexOf(firstPrefixFound, 
        StringComparison.OrdinalIgnoreCase) + prefixLength;
    int endOfName = MyMessage.IndexOfAny(charactersAfterName, startName) - startName;

    if (endOfName < 0) endOfName = MyMessage.Length - startName;

    // Assign the name that we found
    user_firstName = MyMessage.Substring(startName + prefixLength, endOfName);
}

Putting this together in a function might look like the following, which tries to detect a name from an input string. If it finds a name, it returns true and sets the name parameter to the name found, otherwise it returns false and sets the name parameter to the specified defaultValue string:

private static bool TryGetName(string input, string defaultValue, out string name)
{
    var stringsBeforeIntroduction = new List<string>
    {
        "I am called ",
        "My name is ",
        "People call me ",
        "You can call me ",
        "You can refer to me as "
    };

    var charactersAfterName = new char[]
    {
        ' ', ',', '.', '\n', ';', ':'
    };

    var firstPrefixFound = stringsBeforeIntroduction.FirstOrDefault(prefix =>
        input.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) > -1);

    if (firstPrefixFound != null)
    {
        // Calculate the indexes of the start and end of the name
        int prefixLength = firstPrefixFound.Length;
        int startName = input.IndexOf(firstPrefixFound, 
            StringComparison.OrdinalIgnoreCase) + prefixLength;
        int endOfName = input.IndexOfAny(charactersAfterName, startName) - startName;

        if (endOfName < 0) endOfName = input.Length - startName;

        // Assign the name that we found
        name = input.Substring(startName, endOfName);
    }
    else
    {
        name = defaultValue;
        return false;
    }

    return true;
}

And then the usage would look something like:

string name = "stranger";

while (true)
{
    Console.Write("Input some text: ");
    Console.WriteLine(TryGetName(Console.ReadLine(), name, out name)
        ? $"I detected your name is: '{name}'"
        : $"I did not detect your name that time, {name}.");
    Console.WriteLine();
}

And the output looks like:

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM