Reputation: 1
I've been given the task to make a textbox where you enter your personal code (something we in Latvia use). I need it to be validated before saving the information. For validation I've been using Regex but so far got no result.
Our personal code is like this : XXYYZZ-ABCDE, where XXYYZZ is date format as in DAYMONTHYEAR and ABCDE are random numbers.
if (per_kods.Text.Trim() != string.Empty)
{
mRegxExpression = new Regex("${day}-${month}-${year}-#####$");
if (!mRegxExpression.IsMatch(per_kods.Text.Trim()))
{
label7.Text = "";
}
else
{
label7.ForeColor = Color.Red;
label7.Text = "Personas kods ievadīts nepareizi!";
pareizi = false;
}
}
this currently is my code. It basically enables a label above the textbox pointing out that the information entered is wrong. If the information is right, the label continues to be disabled. But right now the new Regex part is a problem. I know it might seem totally wrong, but I've just started learning Regex and don't know what's wrong and what's right.
Upvotes: 0
Views: 122
Reputation: 10563
If you don't care about date validation (so for example 31st of February will be accepted, you can do
new Regex(@"^(0[1-9]|[1-2]\d|3[0-1])(0[1-9]|1[0-2])(\d{2})-(\d{5})$");
If you want to understand what this string means, take a look at the MSDN reference.
Now for date validation, so filtering out dates like 310298
that don't exist, I'd recommend you do it manually afterwards - regex is not the best tool for such logic-validation.
EDIT:
You can accomplish that using DateTime.TryParse
.
DateTime resultDateTime;
var isValid = DateTime.TryParse(string.Format("{0}-{1}-{2}", 2010, 2, 31), out resultDateTime);
// isValid is false, because 31st of February 2010 does not exist.
var isValid = DateTime.TryParse(string.Format("{0}-{1}-{2}", 2010, 2, 27), out resultDateTime);
// isValid is true, and resultDateTime has been set to 27-2-2010.
Note that DateTime.TryParse
is culture sensitive. Depending on the target culture you might need to change the input string. See MSDN reference for TryParse
.
EDIT2:
So to connect this with your existing code:
mRegxExpression = new Regex(@"^(0[1-9]|[1-2]\d|3[0-1])(0[1-9]|1[0-2])(\d{2})-(\d{5})$");
var match = mRegxExpression.Match(per_kods.Text.Trim()));
if(!Validate(match))
{
// Handle invalid.
}
else
{
// Handle valid.
}
Where Validate
would be:
private static bool Validate(Match match)
{
if(!match.Success)
{
return false;
}
var day = match.Groups[1].ToString();
var month = match.Groups[2].ToString();
var year = match.Groups[3].ToString();
return DateTime.TryParse($"{day}-{month}-{year}", out _);
}
Because our regex begins with ^
and ends with $
, there will be always at most one match. The Success
property tells us whether there was any match at all, and later the Groups
property gives us the capture groups. Groups[0]
will be the entire matched string, and then every next one will be the substring that matches one of the parentheses enclosed groups from regex - so the first one is (0[1-9]|[1-2]\d|3[0-1])
which represents days, the second will be months, and so on. Then we just check if the date is valid (again, culture sensitive!). Also, we can neatly use the C#7 discard syntax (_
) for the out
parameter, as we don't need it.
Upvotes: 1
Reputation: 4279
You can get help from the code below to check validation.
public bool CheckValidation(string input)
{
input = input.Trim();
if (input == string.Empty) return false;
var mRegxExpression = new Regex("^([0-2][0-9]|(3)[0-1])(((0)[0-9])|((1)[0-2]))\\d{2}(\\-)\\d{5}$");
return mRegxExpression.IsMatch(input);
}
Upvotes: 0