简体   繁体   中英

C# String Pattern Matching

I have 2 lists of strings in C# showing the players who have joined and left a particular game. I'm trying to attempt to determine who is still in the game by matching both lists and eliminating the entries of those who have left the game. Please suggest a easy and pain free algorithm to go about doing this. My current code is as follows

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]);

        }

Here is some sample input:

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

Are you asking how to get your two lists, or how to find the current players after you've already got the two lists?

The second part can be done with Linq....

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

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

EDIT In response to your comment, having read your question again then obviously the above won't work because you are building your lists in a weird way.

You are storing the whole string in the list, eg user_1 has left the game , what you should probably be doing is just storing the user name. If you correct this then the above code does exactly what you want.

A full example:

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"); 
}

Intersect and Except are your friends.

Also, if this is the sole purpose of the lists, consider using something like HashSet instead.

How about using List.Find()? Link 1 here Link 2 here

use linq and 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();

First you need to extract the player names so you can calculate the difference:

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();

Now calculate the difference:

var playersStillInGame = joinedNames.Except(leftNames);
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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM