循环期间未替换的字符串

本文关键字:字符串 替换 循环 | 更新日期: 2023-09-27 18:01:03

我正在为skype机器人做一个消息循环,这意味着我可以很容易地发布大量消息。但是,在循环中的第一个名称字符串被类中的名称替换后,它将只使用该名称,而不会在下一个循环中替换新名称。

代码:

if(listView2.SelectedItems.Count<=0)
    return;
string value="Hi %name%!";
string body="";
if(Program.InputBox("New Message", "Body of the message:", ref value)==DialogResult.OK) {
    body=value;
}
foreach(ListViewItem i in listView2.SelectedItems) {
    String rawID=i.SubItems[7].ToString();
    String[] splitID=rawID.Split('}');
    String[] ID=splitID[0].Split(new char[] { '{' });
    body=body.Replace("%handle%", SkypeUser.Users[Convert.ToInt32(ID[1])].Handle);
    body=body.Replace("%name%", SkypeUser.Users[Convert.ToInt32(ID[1])].Name);
    body=body.Replace("%status%", SkypeUser.Users[Convert.ToInt32(ID[1])].Status);
    body=body.Replace("%country%", SkypeUser.Users[Convert.ToInt32(ID[1])].Country);
    body=body.Replace("%mood%", SkypeUser.Users[Convert.ToInt32(ID[1])].Mood);
    body=body.Replace("%about%", SkypeUser.Users[Convert.ToInt32(ID[1])].About);
    if(!(body==String.Empty)) {
        skype.SendMessage(SkypeUser.Users[Convert.ToInt32(ID[1])].Handle, body);
    }
}

如果我选择三个人,分别叫Jim、Tim和Derp,那么所选列表上的第一个人就是Jim。如果我使用%name%,在给Jim的消息中,它将被正确地替换为"Jim",但给Tim和Derp的消息也将有"Jim"而不是将%name%替换为其名称的字符串。


编辑:

我知道把valuebody和if语句放在循环中;但我希望只需要输入一次信息。这就是大众信息的全部意义。

循环期间未替换的字符串

下面的语句应该在for循环中。
            string value = "Hi %name%!";
            string body = "";
            if (Program.InputBox("New Message", "Body of the message:", ref value) == DialogResult.OK)
            {
                body = value;
            }

第一次遍历循环时,%%占位符会被有效地销毁。如果你进入:

body = "Hi %name%";

在第一次迭代后,你会得到:

body = "Hi Jim";

当循环第二次运行时,它在"Hi-Jim"中搜索%name%,找不到任何要替换的内容,只保留字符串,最终将"Hi-JJim"发送给Derp。避免修改主体的原始值,并在每次迭代中使用新的变量:

foreach (ListViewItem i in listView2.SelectedItems)
{
   string userBody = body;
   ...
   userBody = userBody.Replace("%name%", SkypeUser.Users[Convert.ToInt32(ID[1])].Name);
   ...
}

还要注意的是,C#中的string类是不可变的,这意味着循环中的每个字符串操作都会创建一个内容已修改的字符串的新实例,并将以前的值保留为要收集的垃圾。如果您进行了重要的字符串操作(并且确实进行了(,请查看StringBuilder类,该类是为在字符串操作中使用而设计的。您的代码看起来有点像:

foreach (ListViewItem i in listView2.SelectedItems)
{
   StringBuilder userBodyBuilder = new StringBuilder(body);
   ...
   userBodyBuilder.Replace("%name%", SkypeUser.Users[Convert.ToInt32(ID[1])].Name);
   ...
}

此代码将比原始代码浪费更少的内存,速度也更快,因此您可以更有效地向联系人发送垃圾邮件:D

我认为,第一次替换数据%XXX%(例如"%name%"(时,下一次通过循环时就不再有它们了。

在循环中使用一个新变量:

foreach[...]
{
  string currentBody = body;
  currentBody = body.Replace[...]
  [...]
}

只需在发送消息后再次替换字符串<3

为您复制的简单代码

if(SkypeUser.Users[Convert.ToInt32(ID[1])].Handle!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Handle, "%handle%");
}
if(SkypeUser.Users[Convert.ToInt32(ID[1])].Name!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Name, "%name%");
}
if(SkypeUser.Users[Convert.ToInt32(ID[1])].Status!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Status, "%status%");
}
if(SkypeUser.Users[Convert.ToInt32(ID[1])].Country!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Country, "%country%");
}
if(SkypeUser.Users[Convert.ToInt32(ID[1])].Mood!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].Mood, "%mood%");
}
if(SkypeUser.Users[Convert.ToInt32(ID[1])].About!=String.Empty) {
    body=body.Replace(SkypeUser.Users[Convert.ToInt32(ID[1])].About, "%about%");
}

这是因为要替换循环中的字符串主体。在循环中创建一个临时变量并分配给它。