2

我的问题是,我正在尝试创建一个基本的脚本程序。我希望它从选定的输入单词中选择一个随机单词。

IE:

Hello {you,uyo,u}, whats up?

然后它将从括号中的一个中随机选择以输出如下内容:

Hello u, whats up?/Hello you, whats up?/Hello uyo, whats up?

到目前为止,这是我尝试过的: 图片

请原谅任何错误的代码,这是我第一次尝试编写脚本。该程序如下所示: 第二张图片

该程序到目前为止工作正常,但我不能在消息中添加任何其他内容,除了争夺{},我希望能够将 {} 扔到任何地方,它会随机选择。

4

3 回答 3

4

您可能需要考虑正则表达式:

using System;
using System.Linq;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        var input = "Hello {you,uyo,u}, whats {up,down}?";
        var random = new Random();
        var result = Regex.Replace(input, @"{.*?}", m =>
        {

            var values = m.Value.Substring(1, m.Value.Length - 2).Split(',');
            return values.ElementAt(random.Next(values.Length));
        });

        Console.WriteLine(result);
    }
}

不过要小心嵌入{{}}。如果您希望这种情况发生,您可能希望:

  1. 编写自己的解析引擎,
  2. 或使用平衡组定义
于 2013-10-25T07:35:01.093 回答
0

你想要这样的东西吗?

string myString = "Hello {you,uyo,u}, whats up?";

string[] stringList = myString.Split('{');
string before = stringList[0];

stringList = stringList[1].Split('}');
string after = stringList[1];

stringList = stringList[0].Split(',');



foreach (string s in stringList)
{
    Console.WriteLine(before+" "+s+""+after);
}

Console.ReadLine();

输出:

Hello you, whats up?
Hello uyo, whats up?
Hello u, whats up?

让它只选择随机词:

Random rand = new Random();

int i = rand.Next(stringList.Length);

Console.WriteLine(before + " " + stringList[i] + "" + after);

此解决方案假定您只能在输入字符串中放置一次方括号。但是您可以轻松地编辑/改进它以处理更多。例如,您可以首先计算字符串中的括号,然后根据它创建一个 foreach 来检索所有可能的值。

于 2013-10-25T06:46:11.650 回答
0

一般使用 indexOf

有很多方法可以做到这一点,但是您确实需要使用 indexOf。

int openBrace = originalString.indexOf("{");

如果 openBrace 为 -1,则未找到。如果您不想处理所有大括号,那么您将需要使用额外的参数选项。

int closingBrace = 0;
int openBrace = 0;
//Loop forever, break logic is inside
while (true) {
    openBrace = originalString.indexOf("{", closingBrace);
    if (openBrace == -1) break;
    closingBrace = originalString.indexOf("}", openBrace);
    if (closingBrace == -1) closingBrace = originalString.Length;

    openBrace++; //Doing this, makes the next statement look nice
    string BraceContents = originalString.SubString(openBrace, closingBrace - openBrace);
}

(可能存在错误,所以如果您需要帮助改进它,请告诉我)

我希望你能明白。您当前使用 split 和 contains 的过程非常有限。

建议的脚本解析架构

但是,为了提高整个脚本处理系统的性能和简单性,您可能希望一次处理一个字符,然后输出到 StringBuilder。

一般使用 indexOf

有很多方法可以做到这一点,但是您确实需要使用 indexOf。

int openBrace = originalString.indexOf("{");

如果 openBrace 为 -1,则未找到。如果您不想处理所有大括号,那么您将需要使用额外的参数选项。

int closingBrace = 0;
int openBrace = 0;
//Loop forever, break logic is inside
while (true) {
    openBrace = originalString.indexOf("{", closingBrace);
    if (openBrace == -1) break;
    closingBrace = originalString.indexOf("}", openBrace);
    if (closingBrace == -1) closingBrace = originalString.Length;

    openBrace++; //Doing this, makes the next statement look nice
    string BraceContents = originalString.SubString(openBrace, closingBrace - openBrace);
}

(可能存在错误,所以如果您需要帮助改进它,请告诉我)

我希望你能明白。您当前使用 split 和 contains 的过程非常有限。

建议的脚本解析架构

但是,为了提高整个脚本处理系统的性能和简单性,您可能希望一次处理一个字符,然后输出到 StringBuilder。

class ScriptParser
{
    //Declare as member variables, to make sub-function calls simpler (not need to have "ref i", for example)
    StringBuilder sb = new StringBuilder();
    int i;
    string scriptString;

    public string Parse(string input)
    {
        scriptString = input; //Share across object

        //Loop through each character one at a time once
        for (i = 0; i < scriptString.Length; i++)
        {
            //I suggest naming your conditions like this, especially if you're going to have more types of commands, and escape sequences in the future.
            bool isRandomCommand = (scriptString[i] == '{'); //What you have described
            bool isSomeOtherCommand = (scriptString[i] == '['); //Dummy
            bool isCommand = isRandomCommand || isSomeOtherCommand; //For later, determines whether we continue, bypassing the direct copy-through default

            //Command processing
            if (isRandomCommand) //TODO: perhaps detect if the next character is double brace, in which case it's an escape sequence and we should output '{'
                ProcessRandomCommand(); //This function will automatically update i to the end of the brace
            else if (isSomeOtherCommand) //Dummy
                ProcessSomeOtherCommand(); //Dummy

            if (isCommand)
                continue; //The next character could be another {} section, so re-evaluate properly

            sb.Append(scriptString[i]); //Else, simply copy through
        }

        return sb.ToString();
    }

    void ProcessRandomCommand()
    {
        //Find the closing brace
        int closingBrace = scriptString.IndexOf("}", i);
        if (closingBrace == -1)
            throw new Exception("Closing brace not found");

        i++; //Makes the next statement nicer
        string randomOptionsDeclaration = scriptString.SubString(i, closingBrace - i);
        i = closingBrace; //Not closingBrace+1, because the caller will continue, and the for loop will then increment i

        string[] randomOptions = randomOptionsDeclaration.Split(',');
        int randomIndex = 0; //TODO: Randomisation here

        sb.Append(randomOptions[randomIndex]);
    }
}
于 2013-10-25T06:53:12.220 回答