字符串在循环期间不被替换

时间:2013-02-25 12:15:05

标签: c# string replace

我正在为 skype bot 做一个消息循环,这意味着我可以轻松地宣传/群发消息。但是,在循环中的第一个名称字符串被类中的名称替换之后,它将仅使用该名称,而不是在下一个循环中替换新名称。

代码:

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语句;但我希望输入消息只需要一次。这就是大众信息的重点。

5 个答案:

答案 0 :(得分:2)

以下语句应该在for循环中。

            string value = "Hi %name%!";
            string body = "";
            if (Program.InputBox("New Message", "Body of the message:", ref value) == DialogResult.OK)
            {
                body = value;
            }

答案 1 :(得分:2)

第一次进行循环时,%%占位符会被有效破坏。如果你参加:

body = "Hi %name%";

在第一次迭代后得到:

body = "Hi Jim";

当循环第二次运行时,它会在&#34中搜索%name%嗨吉姆&#34;,找不到要替换的内容,单独留下字符串,最后发送&#34吉姆&#34;到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

答案 2 :(得分:0)

我认为您第一次更换数据%XXX%(例如"%name%")时,下次传入循环时就不再拥有它们了。

在循环中使用新变量:

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

答案 3 :(得分:0)

发送消息&lt; 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%");
}

答案 4 :(得分:-1)

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