Reputation: 310
I have a situation where users can assign locations to items. locations range from A1 to GG17 I guess it is like a row / column format.. Columns Range from A - GG. After Z will be STRICTLY AA, BB, CC, DD, EE, FF, GG. And rows 1-17
i.e. users can assign location A1, A2, A3, B4, AA1, BB2... GG17
I want to validate the text the user enters when they assigning a location to stop them from adding HH1 or A20 for example..
I am able to achieve this from A - Z, 1-17, but am stumbling when the validation has to go past Z (AA, BB, CC...)
this is what I have for A-Z and 1-17 so far that works
List<char> allowedColumns = new List<char>();
List<int> allowedRows = new List<int>();
char column ='A';
int row = 1;
if (txtAssignLocation.Text != "")
{
while (column <= 'Z')
{
allowedColumns.Add(column);
column++;
}
while (row <= 17)
{
allowedRows.Add(row);
row++;
}
string enteredText = txtAssignLocation.Text;
string enteredColumn = enteredText.Substring(0, 1);
string enteredRow = enteredText.Substring(1);
if (!allowedColumns.Contains(Convert.ToChar(enteredColumn)) || !allowedRows.Contains(Convert.ToInt32(enteredRow)))
{
lblValidationError.Text = "Entered Location does not exist";
}
}
I am at a bit of a loss since Char cannot be more than one character and it and ++ cannot be applied to string
Upvotes: 2
Views: 882
Reputation: 211
new Regex("^[A-Z][A-G]?[1-9][0-7]?$")
validates most of the combinations. Preventing the numbers from 20 to 97 is a bit more tricky. But play around with regular expressions or just split the string and to an int.TryParse
and make sure that the number part is <= 17.
EDIT Yes, it was a bit quick'n'dirty. This one should do the trick:
@"^([A-Z]|([A-G])\2)([1-9]|1[0-7])$"
Example usage:
Regex regex = new Regex(@"^([A-Z]|([A-G])\2)([1-9]|1[0-7])$");
string userInput = "AG20";
bool ok = regex.Match(userInput).Success;
Upvotes: 2
Reputation: 8224
Based on what David said in the comments why not simply have a "hard coded" list of acceptable values since there aren't that many and simply check any entered text against this list?
// This will be a list of all valid locations from 'A1' to 'GG17'
var locations = new HashSet<string>();
// Add all values from 'A1' to 'Z17'
for (char c = 'A'; c <= 'Z'; c++)
{
for (int i = 1; i <= 17; i++)
{
locations.Add($"{c}{i}");
}
}
// Add the values for 'AA1' to 'GG17'
for (char c = 'A'; c <= 'G'; c++)
{
for (int i = 1; i <= 17; i++)
{
locations.Add($"{c}{c}{i}");
}
}
Now you can simply check against this list for validation:
locations.Contains("A1"); // true
locations.Contains("BB10"); // true
locations.Contains("AF7"); // false
locations.Contains("GA10"); // false
Upvotes: 2
Reputation: 319
You can do this with just providing the maxColumn and maxRow in your method (or passed in as variables) instead of an array or other hardcoding of logic. You could enhance this with LINQ, but providing answer as a loop for clarity:
public static bool ValidateInput(string input)
{
//set maxColumn and maxRow sizes
const string maxColumn = "BG";
const int maxRow = 155;
//initialize input parse variables
string inputColumn = "";
int inputRow = int.MaxValue;
//use only upper-case (to aid in comparison)
input = input.ToUpper();
//parse input into inputColumn and inputRow
for (int i = 0; i < input.Length; i++)
{
if (char.IsDigit(input[i]))
{
inputRow = int.Parse(input.Substring(i));
break;
}
inputColumn += input[i];
}
//make sure the length is at least as long as maxColumn (for comparing single letter column to double-letter column, for example)
inputColumn.PadLeft(maxColumn.Length, ' ');
//return comparison result (inclusive to maxColum and maxRow)
return string.Compare(inputColumn, maxColumn) <= 0 && inputRow <= maxRow;
}
UPDATE: If you are interested in the LINQ version, here it is:
public static bool ValidateInput(string input)
{
//set maxColumn and maxRow sizes
const string maxColumn = "BG";
const int maxRow = 155;
//parse input into inputColumn and inputRow
string inputColumn = new string(input.TakeWhile(char.IsLetter).Select(char.ToUpper).ToArray());
int inputRow = int.Parse(new string(input.Skip(inputColumn.Length).ToArray()));
//make sure the length is at least as long as maxColumn (for comparing single letter column to double-letter column, for example)
inputColumn.PadLeft(maxColumn.Length, ' ');
//return comparison result (inclusive to maxColum and maxRow)
return string.Compare(inputColumn, maxColumn) <= 0 && inputRow <= maxRow;
}
Upvotes: 0