Math Student
Math Student

Reputation: 567

Get particular parts from a string

I'm trying to get particular parts from a string. I have to get the part which starts after '@' and contains only letters from the Latin alphabet.

I suppose that I have to create a regex pattern, but I don't know how.

string test = "PQ@Alderaa1:30000!A!->20000";
var planet = "Alderaa"; //what I want to get
string test2 = "@Cantonica:3000!D!->4000NM";
var planet2 = "Cantonica";

There are some other parts which I have to get, but I will try to get them myself. (starts after ':' and is an Integer; may be "A" (attack) or "D" (destruction) and must be surrounded by "!" (exclamation mark); starts after "->" and should be an Integer)

Upvotes: 3

Views: 100

Answers (3)

The fourth bird
The fourth bird

Reputation: 163277

You could get the separate parts using capturing groups:

@([a-zA-Z]+)[^:]*:(\d+)!([AD])!->(\d+)

That will match:

  • @([a-zA-Z]+) Match @ and capture in group 1 1+ times a-zA-Z
  • [^:]*: Match 0+ times not a : using a negated character class, then match a : (If what follows could be only optional digits, you might also match 0+ times a digit [0-9]*)
  • (\d+) Capture in group 2 1+ digits
  • !([AD])! Match !, capture in group 3 and A or D, then match !
  • ->(\d+) Match -> and capture in group 4 1+ digits

Demo | C# Demo

Upvotes: 4

Aleks Andreev
Aleks Andreev

Reputation: 7054

You already have a good answers but I would like to add a new one to show named capturing groups.

You can create a class for your planets like

class Planet
{
  public string Name;
  public int Value1; // name is not cleat from context
  public string Category; // as above: rename it
  public string Value2; // same problem
}

Now you can use regex with named groups

@(?<name>[a-z]+)[^:]*:(?<value1>\d+)!(?<category>[^!]+)!->(?<value2>[\da-z]+)

Demo

Usage:

var input = new[]
{
    "PQ@Alderaa1:30000!A!->20000",
    "@Cantonica:3000!D!->4000NM",
};

var regex = new Regex("@(?<name>[a-z]+)[^:]*:(?<value1>\\d+)!(?<category>[^!]+)!->(?<value2>[\\da-z]+)",
    RegexOptions.IgnoreCase | RegexOptions.Compiled);

var planets = input
    .Select(p => regex.Match(p))
    .Select(m => new Planet
    {
        Name = m.Groups["name"].Value, // here and further we can access to part of input string by name
        Value1 = int.Parse(m.Groups["value1"].Value),
        Category = m.Groups["category"].Value,
        Value2 = m.Groups["value2"].Value
    })
    .ToList();

Upvotes: 2

Pushpesh Kumar Rajwanshi
Pushpesh Kumar Rajwanshi

Reputation: 18357

You can use this regex, which uses a positive look behind to ensure the matched text is preceded by @ and one or more alphabets get captured using [a-zA-Z]+ and uses a positive look ahead to ensure it is followed by some optional text, a colon, then one or more digits followed by ! then either A or D then again a !

(?<=@)[a-zA-Z]+(?=[^:]*:\d+![AD]!)

Demo

C# code demo

string test = "PQ@Alderaa1:30000!A!->20000";
Match m1 = Regex.Match(test, @"(?<=@)[a-zA-Z]+(?=[^:]*:\d+![AD]!)");
Console.WriteLine(m1.Groups[0].Value);

test = "@Cantonica:3000!D!";
m1 = Regex.Match(test, @"(?<=@)[a-zA-Z]+(?=[^:]*:\d+![AD]!)");
Console.WriteLine(m1.Groups[0].Value);

Prints,

Alderaa
Cantonica

Upvotes: 2

Related Questions