C#字符串模式匹配

时间:2011-06-04 08:42:13

标签: c# string-matching

我在C#中有2个字符串列表,显示已加入并离开特定游戏的玩家。我试图通过匹配两个列表并消除那些离开游戏的人的条目来尝试确定谁仍然在游戏中。请建议一个简单,无痛苦的算法来实现这一目标。我目前的代码如下

string input = inputTextBox.Text;
        string[] lines = input.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.None);
        List<string> filteredinput = new List<string>();
        List<string> joinedlog = new List<string>();
        List<string> leftlog = new List<string>();

        for (int i = 0; i<lines.Length; i++)
        {
            if (lines[i].Contains("your game!"))
            filteredinput.Add(lines[i]);
        }

        for (int i =0; i<filteredinput.Count; i++)
        {
            if (filteredinput[i].Contains("joined"))
                joinedlog.Add(filteredinput[i]);

            else if (filteredinput[i].Contains("left"))
                leftlog.Add(filteredinput[i]);

        }

以下是一些示例输入:

{SheIsSoScrewed}[Ping:|]  has joined your game!.
{AngeLa_Yoyo}[Ping:X]  has joined your game!.
{SheIsSoScrewed}  has left your game!(4).

6 个答案:

答案 0 :(得分:2)

您是否在询问如何获取两个列表,或者在获得两个列表后如何找到当前的玩家?

第二部分可以使用Linq ....

List<string> joinedGame;
List<string> leftGame;

List<string> currentInGame 
          = joinedGame.Where(x => !leftGame.Contains(x)).ToList();

编辑为了回复您的评论,再次阅读您的问题,显然上述内容无效,因为您正在以奇怪的方式构建列表。

您将整个字符串存储在列表中,例如user_1 has left the game,你应该做的只是存储用户名。如果你纠正了这个,那么上面的代码完全符合你的要求。

一个完整的例子:

var input = new List<string>()
{
    "user_1 has joined the game",
    "user_2 has joined the game",
    "user_1 has left the game",
    "user_3 has joined the game"
};

var joined = new List<string>();
var left = new List<string>();

foreach(string s in input)
{   
    var idx = s.IndexOf(" has joined the game");
    if (idx > -1)
    {
        joined.Add(s.Substring(0, idx)); 
        continue;
    }

    idx = s.IndexOf(" has left the game");
    if (idx > -1)
    {
        left.Add(s.Substring(0, idx)); 
    }
}

var current = joined.Where(x => !left.Contains(x)).ToList();

foreach(string user in current)
{
    Console.WriteLine(user + " is still in the game"); 
}

答案 1 :(得分:0)

IntersectExcept是您的朋友。

另外,如果这是列表的唯一目的,请考虑使用类似HashSet的内容。

答案 2 :(得分:0)

如何使用List.Find()? Link 1 here Link 2 here

答案 3 :(得分:0)

使用linq和regex:

var join=new Regex("joined.*?your game");    
var joinLog = (from l in lines where join.IsMatch(join) select l).ToList();

var left=new Regex("left.*?your game");    
var leftLog = (from l in lines where left.IsMatch(join) select l).ToList();

答案 4 :(得分:0)

首先,您需要提取玩家名称,以便计算差异:

var join=new Regex("{(.*)}[.*joined.*?your game");
var joinedNames = filteredinput.Select(l => join.Match(l)).Where(m => m.Success).Select(m => m.Groups[1]).Distinct();

var left=new Regex("{(.*)}[.*left.*?your game");
var leftNames = filteredinput.Select(l => left.Match(l)).Where(m => m.Success).Select(m => m.Groups[1]).Distinct();

现在计算差异:

var playersStillInGame = joinedNames.Except(leftNames);

答案 5 :(得分:0)

string input = inputTextBox.Text;
string[] lines = input.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.None);

Regex joinedLeft = new Regex(@"\{([^{}]*)}.*? has (joined|left) your game!");
HashSet<string> inGame = new HashSet<string>();
foreach (string line in lines)
{
    Match match = joinedLeft.Match(line);
    if (!match.Success)
        continue;

    string name = match.Groups[1].Value;
    string inOrOut = match.Groups[2].Value;

    if (inOrOut == "joined")
        inGame.Add(name);
    else
        inGame.Remove(name);
}