繁体   English   中英

使用通配符或“标签”进行用户输入

[英]Using wildcards or “tags” for user input

我最近开始学习C#,没有任何编程经验。 我一直在阅读教程,我正在学习“if”语句。 我正在尝试创建一个简单的用户反馈应用程序,它会询问问题并响应用户输入。

我想要做的是使用某种关键字或标记系统或通配符类型系统(如搜索查询中的*),以允许对输入的响应不完全具体。

例如,在下面的代码中,我使用If和Else语句,是否有办法将userValue设置为不仅仅是“好”或“坏”,而是设置为这两个词的任意数量的变体,(例如“我很好。“)或者让If语句引用一个关键字或标签列表,(可能在其他地方或在外部文件中列出),这样用户可以输入他们感觉到的,并且预定的程序将会启动关于这句话。

我不打算创建某种形式的AI,只是为了制作一个有趣的响应程序。 使用数组是否可能/合理,并以某种方式将其作为If语句调用? 或者是否有另一种更有效的方法来向用户输入提供反馈? 如果这对于这个网站来说太新手了,我很抱歉。 我搜索过互联网,但问题是,我不知道我在寻找什么!

我到目前为止的代码如下:

Console.WriteLine("Hello. How are you?");
        string userValue = Console.ReadLine();

        string message = "";

        if (userValue == "good")
            message = "That's good to hear. Do you want a cup of tea?";

        else if (userValue == "bad")
            message = "I'm sorry to hear that. Shall I make you a coffee?";

        else
            message = "I don't understand. Do you want a cuppa?";

        Console.WriteLine(message);

        string userValueTwo = Console.ReadLine();

        string messageTwo = "";

        if (userValueTwo == "yes")
            messageTwo = "I'll get right onto it!";

        else if (userValueTwo == "no")
            messageTwo = "Right-o. Shutting down...";

        Console.WriteLine(messageTwo);

        Console.ReadLine();

你可以在这里使用正则表达式

using System.Text.RegularExpressions;

...

// If the phrase stats/ends or contains the word "good"  
if (Regex.IsMatch(userValue, @"(^|\s)good(\s|$)", RegexOptions.IgnoreCase)) {
  message = "That's good to hear. Do you want a cup of tea?";
}

我对发布这个答案犹豫不决,因为它使用的LINQ可能会让你感到困惑,因为你只是在学习。 它比可怕的正则表达式更简单! 您可以使用自己的循环来完成此操作,但LINQ只是为您节省了一些代码并使其(可以说)更具可读性:

Console.WriteLine("Hello. How are you?");
string userValue = Console.ReadLine();

string message = "";

string[] goodWords = new string[] { "good", "well", "sweet", "brilliant"};
string[] badWords  = new string[] { "terrible", "awful", "bad", "sucks");

if (goodWords.Any(word => userValue.Contains(word)))
    message = "That's good to hear. Do you want a cup of tea?";

else if (badWords.Any(word => userValue.Contains(word)))
    message = "I'm sorry to hear that. Shall I make you a coffee?";

else
    message = "I don't understand. Do you want a cuppa?";

基本上, Any()函数会查看列表中是否有符合某些条件的单词。 我们使用的标准是userValue字符串是否Contains()该单词。 有趣的look =>语法是一个lambda表达式 ,只是编写匿名函数的快捷方式。 再一次,现在可能有点混乱。

这是一个非LINQ版本,您可能会发现它更容易理解:

void main()
{
    Console.WriteLine("Hello. How are you?");
    string userValue = Console.ReadLine();

    string message = "";

    string[] goodWords = new string[] { "good", "well", "sweet", "brilliant"};
    string[] badWords  = new string[] { "terrible", "awful", "bad", "sucks"};   

    if (DoesStringContainAnyOf(userValue, goodWords))
        message = "That's good to hear. Do you want a cup of tea?";

    else if (DoesStringContainAnyOf(userValue, badWords))
        message = "I'm sorry to hear that. Shall I make you a coffee?";

    else
        message = "I don't understand. Do you want a cuppa?";

    string answer = "I'm really well thanks";        
}

bool DoesStringContainAnyOf(string searchIn, string[] wordsToFind)
{
    foreach(string word in wordsToFind)
        if (searchIn.Contains(word))
            return true;

    return false;
}

一个简单的Contains检查怎么样?

if (userValue.ToLower().Contains("good"))

我还添加了ToLower()案例转换,以便无论如何都可以工作。

如果你想实现一个关键字和程序(函数)列表,我会这样做:

var keywords = new Dictionary<string, System.Func<string>>() {
    { "good", () => "That's good to hear. Do you want a cup of tea?" },
    { "bad", () => "I'm sorry to hear that. Shall I make you a coffee?" }
};

foreach(var keyword in keywords)
{
    if (userValue.ToLower().Contains(keyword.Key))
    {
        message = keyword.Value();
        break;
    }
}

在这种情况下,我使用C#lambda表达式来保存你想要的“程序列表”; 它是一个非常强大的C#功能,允许使用代码作为数据。 现在这些函数只返回常量字符串值,所以它们对你的场景来说有点过分。

尝试使用“包含”方法。 http://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.110).aspx

例:

if (userValue.ToLower().Contains("good"))
        message = "That's good to hear. Do you want a cup of tea?";

以前的所有答案都是有效的,包含许多值得学习的内容。 我想特别注意lower方法,这将有助于你识别'好'和'好'。

此外,为了使列表更完整,您应该知道旧的IndexOf方法,它将返回字符串中子字符串的位置,如果不包含在那里,则返回-1。

但我有一种预感,你的问题也针对如何以更有效的方式编写 Eliza代码(当然这是游戏的名称)的问题。 你肯定想要超过2个问题..?

如果可以轻松扩展提示词和响应而无需再次更改和编译程序,那将是最有趣的。

最简单的方法是将所有数据放入文本文件中; 有很多方法可以做到这一点,但最简单的维护是带有这样的逐行格式:

//The text file eliza.txt:

good=That's good to hear. Do you want a cup of tea?
bad=I'm sorry to hear that. Shall I make you a coffee?
father=Tell me more about your family!
mother=What would you do Daddy?
..
bye=Goodbye. See you soon..

使用File.ReadLines命令读入此内容。 添加一个using System.IO; 到你的程序的顶部,如果它不存在..从那里我建议使用Dictionary<string, string>

    Dictionary<string, string> eliza = new Dictionary<string, string>();
    var lines = File.ReadAllLines("D:\\eliza.txt");
    foreach (string line in lines)
    {
        var parts = line.Split('=');
        if (parts.Length==2) eliza.Add(parts[0].ToLower(), parts[1]);
    }

现在你可以创建一个循环,直到用户说'再见'或什么都没有:

    string userValue = Console.ReadLine();
    do
    {
        foreach (string cue in eliza.Keys)
            if (userValue.IndexOf(cue) >= 0)
            { Console.WriteLine(eliza[cue]); break; }
        userValue = Console.ReadLine().ToLower();
    }
    while (userValue != "" && userValue.IndexOf("bye") < 0);

有趣的事情是扩展的提示词列表,响应列表,删除一些响应后使用或投入几个随机响应..

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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