如何拆分具有多个分隔符的字符串

时间:2016-10-16 03:44:24

标签: c# string c#-4.0 split

编辑:我应该更好地表达这个问题。我不会删除它,而是留在这里供其他人学习。

一直在研究这个问题,我还没有找到另一个回答此问题的帖子。

我想要拆分的列表如下所示:

0. Yersinia Pestis, 76561198010013870
1. CatharsisLtd., 76561198056110126
2. Nut~Taco, 76561198072105032 

这是玩家姓名和身份证号码的列表。我想删除x。从每一行的开头,以及ID号前面的,,这样我就会得到一个如下所示的列表:

Yersinia Pestis
76561198010013870
CatharsisLtd.
76561198056110126
Nut~Taco
76561198072105032 

我以为我通过使用类似的东西找到了解决方案:

string [] split = strings .Split(new Char [] {',' , '\n' });

但这不起作用,因为玩家可以拥有像“,”这样的东西。以及其名称中的其他符号。我确信有办法做一些像

这样的事情
string splitter = i.ToString()+". ";
and then something like ", any17DigitNumber"

任何帮助都将非常感激,我完全不知道如何使这项工作适用于所有情况。唯一的常量是索引和ID的长度。

5 个答案:

答案 0 :(得分:2)

可能有以下几点:

public class Player
{
    public int Index { get; set; }
    public long Id { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return string.Format("Player(Index={0}, Id={1}, Name={2})", Index, Id, Name);
    }
}

public static Player ParsePlayer(string line)
{
    var dot = line.IndexOf(".");
    var comma = line.LastIndexOf(",");
    return
        new Player
        {
            Index = int.Parse(line.Substring(0, dot).Trim()),
            Id = long.Parse(line.Substring(comma + 1).Trim()),
            Name = line.Substring(dot + 1, comma - (dot + 1)).Trim()
        };
}

public static void Main()
{
    var data = new[] {
        "0. Yersinia Pestis, 76561198010013870",
        "1. CatharsisLtd., 76561198056110126",
        "2. Nut~Taco, 76561198072105032",
        "3. Smith, John, 76561198072105033",
        " 4.Allen, Paul,76561198072105034 "
    };

    var players = new List<Player>();

    // parse
    foreach (var line in data)
    {
        players.Add(ParsePlayer(line));
    }

    // check
    foreach (var player in players)
    {
        Console.WriteLine(player);
    }
}

可测试here

正如Reddy在评论中建议的那样,您也可以尝试使用命名捕获组的正则表达式:

public static Player ParsePlayer(string line)
{
    var regex = new Regex(@"\s*(?<index>[0-9]+)\s*\.\s*(?<name>.+)\s*,\s*(?<id>[0-9]+)\s*");
    var match = regex.Match(line);
    return
        new Player
        {
            Index = int.Parse(match.Groups["index"].Value),
            Id = long.Parse(match.Groups["id"].Value),
            Name = match.Groups["name"].Value
        };
}

可测试here

&#39;希望这会有所帮助。

答案 1 :(得分:1)

如果您的列表始终分为三列,例如示例中提供的列:

0. Yersinia Pestis, 76561198010013870
1. CatharsisLtd., 76561198056110126
2. Nut~Taco, 76561198072105032

你希望它们分开并只获得最后两列,那你为什么不首先用<Space>分割字符串,然后:

  1. 使用shift()省略第一列。您可以查看How to shift the start of an array in C#?
  2. pop()最后一列,基本上是ID号
  3. 使用<space>将其余列重新加入()并删除最后一个字符,即逗号。
  4. 这样你就得到了你想要的东西。

答案 2 :(得分:1)

我喜欢这种方法:

var source = @"0. Yersinia Pestis, 76561198010013870
1. CatharsisLtd., 76561198056110126
2. Nut~Taco, 76561198072105032";

var results =
    source
        .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
        .Select(x => x.Substring(x.IndexOf('.') + 2))
        .SelectMany(x => new []
        {
            x.Substring(0, x.LastIndexOf(',')),
            x.Substring(x.LastIndexOf(',') + 2)
        });

它给了我:

results

或者,您可以将.SelectMany替换为:

        .Select(x => new
        {
            Name = x.Substring(0, x.LastIndexOf(',')),
            Id = x.Substring(x.LastIndexOf(',') + 2)
        });

...然后你得到:

results

答案 3 :(得分:0)

string data = "...";
var matches = new Regex("...(.+?),\\s([0-9]+)?").Matches(data);
for (int i = 0; i < matches.Count; i++) { 
    Console.WriteLine(matches[i].Groups[1].Value);
    Console.WriteLine(matches[i].Groups[2].Value);
}

https://dotnetfiddle.net/GixJ4y

答案 4 :(得分:0)

感谢那些发布解决方案的人。由于我得到的服务器响应方式,我无法使用任何一种,但它们都让我朝着正确的方向前进。以下是我最终需要做的是为发送命令的人获取我想要的ID: `//从两台服务器上抓取所有在线玩家                     string centerPlayers = await messenger.ExecuteCommandAsync(&#34; ListPlayers&#34;);                     string scorchedPlayers = await messengerB.ExecuteCommandAsync(&#34; ListPlayers&#34;);

                //use players discord ID number to locate them in playerData, then find users in game name from there
                bool foundPlayer = false;
                for (int i = 0; i < playerData.Count / 10 - 1; i++)
                {
                    if(playerData[i*10+9] == discordID)
                    {
                        Console.WriteLine("Player found in playerData");
                        if (centerPlayers.Contains(playerData[i * 10]))
                        {
                            Console.WriteLine("Player found online on center");
                            foundPlayer = true;
                            //break off user's steam ID from centerPlayers
                            string name = playerData[i * 10]+ ", ";
                            string[] temp = Regex.Split(centerPlayers, name);
                            string tempb = temp[1];
                            string[] tempc = tempb.Split(' ');
                            Console.WriteLine("Steam ID:" + tempc[0]);
                            //can give gold here, then break
                        }
                        else if (scorchedPlayers.Contains(playerData[i * 10]))
                        {
                            foundPlayer = true;
                            Console.WriteLine("Player found online on scorched");
                            //break off user's steam ID from centerPlayers
                            //can give gold here, then break
                        }
                        else
                        {
                            foundPlayer = true;
                            Console.WriteLine("Player is not online");
                            break;
                        }
                    }

长话短说,这是一个通过RCON管理游戏服务器的不和谐机器人。所有玩家数据都存储在一个数组中。玩家可以将他们的游戏角色链接到他们的不和谐ID,这允许他们通过机器人跟踪的游戏时间获得积分。这个方法允许我搜索playerData [],查看是否存在不和谐ID,如果是,我可以遍历几个地方并获得游戏名称中的玩家。一旦我有了名字,我就可以搜索在线玩家列表。我将名单拆分为名称+&#34;,&#34;然后在下一个空间再次拆分。这给了我列表中的正确ID。现在我知道该播放器已在线,并已注册。现在玩家可以通过不和交换积分,然后机器人可以在适当的服务器上使用RCON(这可以监控两个不同的服务器),为玩家提供金牌。

再次感谢您的帮助:)