简体   繁体   中英

Using RegEx to split strings after specific character

I've been working on trying to get this string split in a couple different places which I managed to get to work, except if the name had a forward-slash in it, it would throw all of the groups off completely.

The string:

123.45.678.90:00000/98765432109876541/[CLAN]PlayerName joined [windows/12345678901234567]

I essentially need the following:

  • IP group: 123.45.678.90:00000 (without the following /)
  • id group: 98765432109876541
  • name group: [CLAN]PlayerName
  • id1 group: 12345678901234567

The text "joined" also has to be there. However windows does not.

Here is what I have so far:

(?<ip>.*)\/(?<id>.*)\/(.*\/)?(?<name1>.*)( joined.*)\[(.*\/)?(?<id1>.*)\]

This works like a charm unless the player name contains a "/". How would I go about escaping that?

Any help with this would be much appreciated!

Since you tag your question with C# and Regex and not only Regex , I will propose an alternative. I am not sure if it will more efficient or not. I find it easiest to read and to debug if you simply use String.Split() :

Demo

public void Main()
{
    string input = "123.45.678.90:00000/98765432109876541/[CLAN]Player/Na/me joined [windows/12345678901234567]";

    // we want "123.45.678.90:00000/98765432109876541/[CLAN]Player/Na/me joined" and "12345678901234567]"
    // Also, you can remove " joined" by adding it before " [windows/"
    var content = input.Split(new string[]{" [windows/"}, StringSplitOptions.None);

    // we want ip + groupId + everything else
    var tab = content[0].Split('/');

    var ip = tab[0];
    var groupId = tab[1];
    var groupName = String.Join("/", tab.Skip(2)); // merge everything else. We use Linq to skip ip and groupId
    var groupId1 = RemoveLast(content[1]); // cut the trailing ']'

    Console.WriteLine(groupName);
}

private static string RemoveLast(string s)
{
    return s.Remove(s.Length - 1);
}

Output:

[CLAN]Player/Na/me joined

If you are using a class for ip, groupId, etc. and I guess you do, just put everything in it with a constructor which accept a string as parameter.

You basically needs to use non greedy selectors ( *? ). Try this:

(?<ip>.*?)\/(?<id>.*?)\/(?<name1>.*?)( joined )\[(.*?\/)?(?<id1>.*?)\]

You shouldn't be using greedy quanitifiers ( * ) with an open character such as . . It won't work as intended and will result in a lot of backtracking.

This is slightly more efficient, but not overly strict:

^(?<ip>[^\/\n]+)\/(?<id>[^\/]+)\/(?<name1>\S+)\D+(?<id1>\d+)]$

Regex demo

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