Regex Expression to extract 2 integer value from string in C# - c#

I have real time response from web service as follows :
ok,SIP/2417,15,default,N
I can save this in text file.
The only thing change is 2417 and 15.
Now I want to explode 2417 and 15 from text file and save in variable or database.
For Database I have Column Ext and Ringtime

This should work:
var test = "ok,SIP/2417,15,default,N";
var regex = new Regex("^ok,SIP/(?<number1>\\d+),(?<number2>\\d+),default,N$");
var match = regex.Match(test);
var val1 = match.Groups["number1"].Value;
var val2 = match.Groups["number2"].Value;
But this would also work:
var test = "ok,SIP/2417,15,default,N";
var values = test.Split(',');
var val1 = values[1].Substring(4);
var val2 = values[2];
Note that they will still be strings at this stage, so you'll need to parse them if you require them as integers:
var number1 = int.Parse(val1);
var number2 = int.Parse(val2);
** TryParse is a better option if you go with the Split option.
Try it online

If you want to have a generic regex you can try is
Regex r = new Regex(#"([\d]+,[\d]+)");
string var = "ok,SIP/2417,15,default,N";
Match match = r.Match(var);
if you want list of those vars then below is the dynamic solution for any count of number.
List<int> vals = new List<int>();
vals.AddRange(match.Groups[0].Value.Split(',').Select(x => Convert.ToInt32(x)));
else if you're going to have fixed two values then.
int val = Convert.ToInt32(match.Groups[0].Value.Split(',')[0]);
int val2 = Convert.ToInt32(match.Groups[0].Value.Split(',')[1]);

Related

better ways to combine two array items into one string

Hello Please could you suggest better ways of writing this C# code.
Basically when NumberList has missing values between '-' I am trying to rebuild the String with default Values.
The final result should be "123-10-45-9-09"
As you can see value of "second-10" is replaced as the second item in the string.
10, 9 and 09 are filled in from the value string values.
This is the bad string which is missing some values.
string NumberList = "123--45--";
I have stored this string value in my app.config file.
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
protected string MissingNumberString(string Number)
{
string NumberList = "123--45--";
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
var companyAccountList = valuestring.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var result = NumberList.Split('-');
int counter = 0;
var builder = new System.Text.StringBuilder();
foreach (string s in companyAccountList)
{
string t = s.Substring(s.IndexOf('-') + 1);
if (string.IsNullOrEmpty(result[counter]))
builder.Append(t).Append("-");
else
{
if (companyAccountList.Length == counter)
builder.Append(result[counter]);
else
builder.Append(result[counter]).Append("-");
}
counter++;
}
return builder.ToString();
}
One way (assuming valuestring is in order and do not miss any defaults) to achieve this would be
string MissingNumber(string Number)
{
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
var regex = Regex.Matches(valuestring,#"(?<=-)(\d*)(?<=,)?");
var defaults = regex.Cast<Match>().Select(x=>x.Value).ToList();
var newArray = Number.Split('-').Select((x,index)=>string.IsNullOrEmpty(x)?defaults[index]:x);
return string.Join("-",newArray);
}
The code uses Regular Expression to break the ValueString and read the default values.
Regex.Matches(valuestring,#"(?<=-)(\d*)(?<=,)?");
The regular expression uses non-capturing groups to capture a number which is prefixed as by an optional "-" character and suffixed by an optional "," character.
Once the defaults are parsed into a List (assuming that the positions are in order and do not miss any values), we loop through the input string (which has been split based on delimiter), check if it is Empty, and if so, use the value from the Defaults (based on our assumption, it should have same index).
Update
Based on the comments, it looks like you other data in the original string, and hence the concerned sub-string has to be captured first.
We could update the Missing Number method as
static string MissingNumber(string Number)
{
string valuestring = "first-12,second-10,third-99,fourth-9,fifth-09";
var regexDefaultValues = Regex.Matches(valuestring,#"(?<=-)(\d*)(?<=,)?");
var defaults = regexDefaultValues.Cast<Match>().Select(x=>x.Value).ToList();
var regexNumberToParse = new Regex(#"(\d)*-(\d)*-(\d)*-(\d)*-(\d)*");
var capturedNumberFormat = regexNumberToParse.Match(Number).Value;
var newArray = capturedNumberFormat.Split('-').Select((x,index)=>string.IsNullOrEmpty(x)?defaults[index]:x);
var ValueWithDefaults = string.Join("-",newArray);
return regexNumberToParse.Replace(Number,ValueWithDefaults);
}
Demo Code

Compare two values and get data in between them

I have two variables 2016-V-0049 and 2016-V-0070. Is there a way in which I can compare them and get all the missing data between them while comparing the last numbers. So in this case I want the result to be 2016-V-0050,2016-V-0051,2016-V-0052...etc.
Also can I have repeatable patterns like comparing 2016P13 and 2016P25(NumberWordNumber) and getting the missing numbers in between.
Sorry for not including what I have tried. Here's what I did and which works. I was just looking for more patterns which are generic.
string s = "2016-s-89";
string p = "2016-s-95";
var start = Convert.ToInt32(Regex.Match(s, #"\d+$").Value) +1;
var end = Convert.ToInt32(Regex.Match(p, #"\d+$").Value);
var index = Regex.Match(s, #"\d+$").Index;
string data = s.Substring(0, index);
List<string> newCases = new List<string>();
while (start < end)
{
string newCaseNumber = string.Format("{0}{1}", data, start);
newCases.Add(newCaseNumber);
start++;
}
Once you can define step by step what you actually want your code to do, the implementation is trivial to research and put together. In steps, you want this:
Parse the input string denoting the starting number, so you can obtain the numeric part you're interested in.
Now you have a numeric string, but it's still a string. Parse it to an integer so you can later perform arithmetic operations on it, such as incrementing it by one.
Repeat 1 & 2 for the string denoting the ending number.
Loop over the numbers between the start and end number, and rebuild the original string with the new number.
A naive implementation to do that looks like this:
string inputStart = "2016-V-0049";
string inputEnd = "2016-V-0070";
string pattern = #"[0-9]{4}\-[A-Z]{1}\-([0-9]{4})";
var regex = new Regex(pattern);
var match = regex.Match(inputStart);
var numberStart = int.Parse(match.Groups[1].Value);
match = regex.Match(inputEnd);
var numberEnd = int.Parse(match.Groups[1].Value);
for (int currentNumber = numberStart + 1; currentNumber < numberEnd; currentNumber++)
{
Console.WriteLine("2016-V-{0:0000}", currentNumber);
}
But this doesn't do input checking (start < end, start and end actually conforming to the pattern), doesn't support different patterns (the pattern and rebuild string are hardcoded) and assumes the "2016-V-" part of the string to always be the same.
You should use substring() function and convert to integer like this code:
var min = "2016-V-0049";
var max = "2016-V-0070";
var a = min.Substring(7);
var b = max.Substring(7);
int convertableVariable1 = int.Parse(a);
int convertableVariable2 = int.Parse(b);
for (int i = convertableVariable1; i < convertableVariable2; i++){
Console.WriteLine("2016-V-{0:0000}",i);
}
Console.WriteLine("Difference :{0}", convertableVariable2 - convertableVariable1);

Parsing string with 3 hyphens C#

I have string COO70-123456789-12345-1. I need to parse based on the "-" not the length of the substrings and use the parsed values. I have tried using Regular expressions but having issues.Please suggest.
Also after I have split the values I need to use each values: string A = COO70, int B = 123456789, int C = 12345, short D = 1 . How do I get it in different variables A,B,C,D.
string[] results = UniqueId.Split('-');
string A = results[0];
string B = results[1];
string C = results[2];
int k_id = Convert.ToInt32(k_id);
string D = results[3];
short seq = Convert.ToInt16(seq);
string s = "COO70-123456789-12345-1";
string[] split = s.Split('-'); //=> {"COO70", "123456789", "12345", "1"}
Use indexOf
To find everything before the first hyphen use:
string original= "COO70-123456789-12345-1";
string toFirstHyphen=original.Substring(0,original.IndexOf("-"));
Or if you want every section use split like the above example.
You can verify whether the input is formatted as you want and then split to get the parts.
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string pattern = #"(?x)^(\w+-\w+-\w+-\w+)$";
Regex reg = new Regex(pattern);
string test = "word-6798-3401-001";
if((reg.Match(test).Success))
foreach (var x in test.Split(new char[] {'-'}))
Console.WriteLine(x);
}
}
So it sounds like you first want to split it, but then store it into your values.
I would do something like this:
var myString = "COO70-123456789-12345-1";
var stringSet = myString.Split("-"); // This returns an array of values.
Now we need to verify that we receive only 4 sub strings:
if (stringSet.Count != 4)
throw Exception e; // Throw a real exception, not this
From here we need to know what order our strings should be in and assign them:
var A = stringSet[0];
var B = stringSet[1];
var C = stringSet[2];
var D = stringSet[3];
While this should answer your question as posed, I would recommend you work with stringSet differently personally.

split string c# based on math operator

(Calculator program)count in one step with math basic order
if there is a string = "5+2*6/9"(which is user input) how to get number 2 and 6?
i've been trying with split but if there is no '+' it fail :(
here is my code atm
string[] a = kalimat.Split('*');
string[] a1 = a[0].Split('+');
string[] a2 = a1[a1.Count() - 1].Split('-');
string[] b1 = a[1].Split('+');
string[] b2 = b1[0].Split('-');
ang1 = a2[a2.Count() - 1];
ang2 = b2[0];
angka1 = Convert.ToDouble(ang1);
angka2 = Convert.ToDouble(ang2);
hasil = angka1 * angka2;
any idea guys?
If you're input expression is always in the form: "[some number]+[first value you want to return]*[second value you want to return]" then this should work for you:
var reg = new System.Text.RegularExpressions.Regex(#"\d\+(\d)\*(\d)");
var result = reg.Match("5+2*6/9");
var first = result.Groups[1];
var second = result.Groups[2];
You can of course tweak the regular expression search pattern to suit your needs.
Parsing arbitrary mathematical expression is not a trivial task. If this isn't a homework that require you to do the parsing by hand, I would suggest to find a library for doing the task, like NCalc for example.
You can install it from Nuget, and use the following simple code :
var kalimat = "5+2*6/9";
var hasil = new NCalc.Expression(kalimat).Evaluate();
Console.WriteLine(hasil);
Selamat mencoba :)

Parse multiple values from string c#

Suppose I have written "5 and 6" or "5+6". How can I assign 5 and 6 to two different variables in c# ?
P.S. I also want to do certain work if certain chars are found in string. Suppose I have written 5+5. Will this code do that ?
if(string.Contains("+"))
{
sum=x+y;
}
string input="5+5";
var numbers = Regex.Matches(input, #"\d+")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
Personally, I would vote against doing some splitting and regular expression stuff.
Instead I would (and did in the past) use one of the many Expression Evaluation libraries, like e.g. this one over at Code Project (and the updated version over at CodePlex).
Using the parser/tool above, you could do things like:
A simple expression evaluation then could look like:
Expression e = new Expression("5 + 6");
Debug.Assert(11 == e.Evaluate());
To me this is much more error-proof than doing the parsing all by myself, including regular expressions and the like.
You should use another name for your string than string
var numbers = yourString.Split("+");
var sum = Convert.ToInt32(numbers[0]) + Convert.ToInt32(numbers[1]);
Note: Thats an implementation without any error checking or error handling...
If you want to assign numbers from string to variables, you will have to parse string and make conversion.
Simple example, if you have text with only one number
string text = "500";
int num = int.Parse(text);
Now, if you want to parse something more complicated, you can use split() and/or regex to get all numbers and operators between them. Than you just iterate array and assign numbers to variables.
string text = "500+400";
if (text.Contains("+"))
{
String[] data = text.Split("+");
int a = int.Parse(data[0]);
int b = int.Parse(data[1]);
int res = a + b;
}
Basicly, if you have just 2 numbers and operazor between them, its ok. If you want to make "calculator" you will need something more, like Binary Trees or Stack.
Use the String.Split method. It splits your string rom the given character and returns a string array containing the value that is broken down into multiple pieces depending on the character to break, in this case, its "+".
int x = 0;
int y = 0;
int z = 0;
string value = "5+6";
if (value.Contains("+"))
{
string[] returnedArray = value.Split('+');
x = Convert.ToInt32(returnedArray[0]);
y = Convert.ToInt32(returnedArray[1]);
z = x + y;
}
Something like this may helpful
string strMy = "5&6";
char[] arr = strMy.ToCharArray();
List<int> list = new List<int>();
foreach (char item in arr)
{
int value;
if (int.TryParse(item.ToString(), out value))
{
list.Add(item);
}
}
list will contains all the integer values
You can use String.Split method like;
string s = "5 and 6";
string[] a = s.Split(new string[] { "and", "+" }, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(a[0].Trim());
Console.WriteLine(a[1].Trim());
Here is a DEMO.
Use regex to get those value and then switch on the operand to do the calculation
string str = "51 + 6";
str = str.Replace(" ", "");
Regex regex = new Regex(#"(?<rightHand>\d+)(?<operand>\+|and)(?<leftHand>\d+)");
var match = regex.Match(str);
int rightHand = int.Parse(match.Groups["rightHand"].Value);
int leftHand = int.Parse(match.Groups["leftHand"].Value);
string op = match.Groups["operand"].Value;
switch (op)
{
case "+":
.
.
.
}
Split function maybe is comfortable in use but it is space inefficient
because it needs array of strings
Maybe Trim(), IndexOf(), Substring() can replace Split() function

Categories