regex - How to Split Year month Day,if Year does not exist in the given string using c#?


Keywords:c# 


Question: 

Here the below code am working for Split the number from the given string and stores the correspond integer into combobox.That working Perfect.But i want to know ,If Year does not exist in the string,how to assign Year as Zero and the next integer for month strores in second combobox

For example :If string is "4Month(s)2Day(s)" Here No Year,So how to check Year not contains and insert Zero to combobox1,4 to combobox2 and 2 to combobox3

in the following code

int count = 0;
string[] delimiterChars = {"Year","Years","Years(s)","Month","Month(s)","Day","Day(s)"};
string variable =agee;

string[] words = variable.Split(delimiterChars, StringSplitOptions.None);
foreach (string s in words)
{              
    var data = Regex.Match(s, @"\d+").Value;
    count++;
    if (count == 1)
    {
        comboBox1.Text = data;
    }
    else if (count == 2)
    {
        comboBox2.Text = data;
    }
    else if (count == 3)
    {
        comboBox3.Text = data;
    }
}

6 Answers: 

You can do with Regex like this

int combBox1, combBox2, combBox3;
var sample = "1Year(s)4month(s)2DaY(s)";

var yearString = Regex.Match(sample, @"\d+Year", RegexOptions.IgnoreCase).Value;
if (!string.IsNullOrEmpty(yearString))
    combBox1 = int.Parse(Regex.Match(yearString, @"\d+").Value);
var monthString = Regex.Match(sample, @"\d+Month", RegexOptions.IgnoreCase).Value;
if (!string.IsNullOrEmpty(monthString))
    combBox2 = int.Parse(Regex.Match(monthString, @"\d+").Value);
var dayStrings = Regex.Match(sample, @"\d+Day", RegexOptions.IgnoreCase).Value;
if (!string.IsNullOrEmpty(dayStrings))
    combBox3 = int.Parse(Regex.Match(dayStrings, @"\d+").Value);

You can skip the int.Parse() if you want, then you have to set 0 manually.

 

Instead of first splitting the string and then using a RegEx to parse the parts, I'd use a RegEx for the entire work.

Using Regex Hero's tester (requires Silverlight to work...) I came up with the following:

(?:(?<years>\d+)Year\(?s?\)?)?(?<months>\d+)Month\(?s?\)?(?<days>\d+)Day\(?s?\)?

This matches all of the following inputs

Input                                Matching groups:
*****                                ****************
4Month(s)2Day(s)                     months: 4, days: 2
1Year(s)4Month(s)2Day(s)             years: 1, months: 4, days: 2
3Years6Month(s)14Day(s)              years: 3, months: 6, days: 14
1Year1Month1Day                      years: 1, months, 1, days: 1

As you see, it matches everything that's there. If you don't have a match for years, you can test for that with the Success property of the capture group.

Sample

var pattern = @"(?:(?<years>\d+)Year\(?s?\)?)?(?<months>\d+)Month\(?s?\)?(?<days>\d+)Day\(?s?\)?";
var regex = new Regex(pattern);

var testCases = new List<string> {
    "4Month(s)2Day(s)",
    "1Year(s)4Month(s)2Day(s)",
    "3Years6Month(s)14Day(s)",
    "1Year1Month1Day"
};

foreach (var test in testCases) {
    var match = regex.Match(test);

    var years = match.Groups["years"].Success ? match.Groups["years"].Value : "0";
    var months = match.Groups["months"].Value;
    var days = match.Groups["days"].Value;

    string.Format("input: {3}, years: {0}, months: {1}, days: {2}", years, months, days, test).Dump();
}

Run that in LinqPad, and you'll see

input: 4Month(s)2Day(s), years: 0, months: 4, days: 2
input: 1Year(s)4Month(s)2Day(s), years: 1, months: 4, days: 2
input: 3Years6Month(s)14Day(s), years: 3, months: 6, days: 14
input: 1Year1Month1Day, years: 1, months: 1, days: 1
 

I think you have another problem here. If you split the string, you don't now if the value is a year, month or day. This information get lost with splitting. Maybe you should parse the string another way, to get this information.

 

You can create 3 boolean variables to check whether you have year day and month in your string, and check that boolean variable before assigning value to that combobox.

if(variable.Contains("Year"))
             bool  Hasyear = true;
if(variable.Contains("Month"))
             bool  HasMonth= true;
if(variable.Contains("Day"))
             bool  HasDay= true;
 

Use a better pattern

           string input1 = "1Year(s)4Month(s)2Day(s)";
            string pattern1 = @"(?'year'\d+)?(Year(\(s\))?)?(?'month'\d+)(Month(\(s\))?)?(?'day'\d+)(Day(\(s\))?)?";

            Match match1 = Regex.Match(input1, pattern1);

            string year1 = match1.Groups["year"].Value;
            string month1 = match1.Groups["month"].Value;
            string day1 = match1.Groups["day"].Value;

            string input2 = "4Month(s)2Day(s)";
            string pattern2 = @"(?'year'\d+)?(Year(\(s\))?)?(?'month'\d+)(Month(\(s\))?)?(?'day'\d+)(Day(\(s\))?)?";

            Match match2 = Regex.Match(input2, pattern2);

            string year2 = match2.Groups["year"].Value;
            string month2 = match2.Groups["month"].Value;
            string day2 = match2.Groups["day"].Value;​
 

You could very simply do like this:

string agee = "1Year4Month(s)2Day(s)";

string[] delimiterChars = {"Year", "Month", "Day"};
string variable =agee.Replace("(s)","").Replace("s", "");

string[] words = variable.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
int count = words.Length;

switch (count)
{
    case 0:
        combobox1.Text = "0";
        combobox2.Text = "0";
        combobox3.Text = "0";
        break;
    case 1:
        combobox1.Text = "0";
        combobox2.Text = "0";
        combobox3.Text = words[0];
        break;
    case 2:
        combobox1.Text = "0";
        combobox2.Text = words[0];
        combobox3.Text = words[1];
        break;
    case 2:
        combobox1.Text = words[0];
        combobox2.Text = words[1];
        combobox3.Text = words[2];
        break;
}