Reputation: 41
I have a string containing this text...
1. G66I11.J270.P5.C90.(+K2H1+)
2. G66I11.J90.P-5.(+K2H1+)
3. G66I215.4J270.P-55.Q-6.T2531(+K2H1+)
...
I need to extract the value after character "P" is 5 or 55.
Now I'm using IndexOf to get:
int indexP = 0;
int number;
if (lines.Contains("P-"))
{
indexP = lines.IndexOf("P-") + 1;
}
else if (lines.Contains("P") && !lines.Contains("P-"))
{
indexP = lines.IndexOf("P");
}
if (lines.Contains("Q"))
{
int indexQ = 0;
if (lines.Contains(".Q"))
{
indexQ = lines.IndexOf(".Q");
}
if (indexQ > indexP)
{
number = Int.Parse(lines.Substring(indexP + 1, indexQ - indexP - 1));
}
}
if (lines.Contains("C"))
{
int indexC = 0;
if (lines.Contains(".C"))
{
indexC = lines.IndexOf(".C");
}
if (indexC > indexP)
{
number = Int.Parse(lines.Substring(indexP + 1, indexC- indexP - 1));
}
}
...
I returned exactly but after "P" character can be any character.
So if do it this way it will be very long code :(
i want to find a shorter way. Can you show me how to do something? Thanks.
Upvotes: 1
Views: 2303
Reputation: 163642
You could use a pattern to match P followed by an optional -
and then capture the numbers 0-9 in a group.
P-?([0-9]+)
P-?
Match P
and optional -
([0-9]+)
Capture 1 or more digits 0-9 in group 1See a .NET regex demo (click on the table tab) and a C# demo.
For example
string pattern = @"P-?([0-9]+)";
string s = @"1. G66I11.J270.P5.C90.(+K2H1+)
2. G66I11.J90.P-5.(+K2H1+)
3. G66I215.4J270.P-55.Q-6.T2531(+K2H1+)
G98X30.Y292.5I87.75J18.5P5K6";
var numbers = Regex.Matches(s, pattern)
.Select(i => int.Parse(i.Groups[1].Value))
.ToArray();
Console.WriteLine("[{0}]", string.Join(", ", numbers));
Output
[5, 5, 55, 5]
Upvotes: 1
Reputation: 432
Try this - assuming your 'lines' is a multi-line string like so.
string lines = @"
1. G66I11.J270.P5.C90.(+K2H1+)
2. G66I11.J90.P-5.(+K2H1+)
3. G66I215.4J270.P-55.Q-6.T2531(+K2H1+)
";
Regex regex = new Regex(@"[^P]*P-?([^\.]+)\.");
var matches = regex.Matches(lines);
Console.WriteLine($"Count: {matches.Count}");
foreach (Match match in matches)
{
Console.WriteLine($"{match.Groups[1].Value}");
}
// Count: 3
// 5
// 5
// 55
For a single line:
Regex regex = new Regex(@"[^P]*P-?([^\.]+)\.");
string line = "1. G66I11.J270.P5.C90.(+K2H1+)";
var match = regex.Match(line);
Console.WriteLine($"{match.Groups[1].Value}");
// 5
Upvotes: 0
Reputation: 11364
You could use a Regex
and match expression. Something like this,
// Example input
List<string> input = new List<string>();
input.Add("G66I11.J270.P5.C90.(+K2H1+)");
input.Add("G66I11.J90.P-5.(+K2H1+)");
input.Add("G66I215.4J270.P-55.Q-6.T2531(+K2H1+)");
input.Add("G66I11.J90.X-5.(+K2H1+)");
Regex match = new Regex(@"(?<=P)-*\d+(?=.)");
var values = input.Select(x => match.Match(x)?.Value).Where(x => !string.IsNullOrEmpty(x)).ToList();
// values =
Count = 3
[0]: "5"
[1]: "-5"
[2]: "-55"
Regex(@"(?<=P)-*\d+(?=.)");
-> this checks for P
from the start.. and after finding it, it takes 0 or more -
.. takes the number (\d+) until there is a .
.
Only caveat to this is.. it only selects the first match. If you want multiple matches, switch the match.Match
to match.Matches
method which gives you a list of values. you'll have to update the Select statement to return all values.
Upvotes: 3