根据一系列可接受的值验证用户的输入

时间:2017-09-05 14:41:12

标签: c# winforms

我有一种情况,用户可以为项目分配位置。 地点范围从A1到GG17 我想它就像一个行/列格式。列范围来自A - GG。 Z之后将是STRICTLY AA,BB,CC,DD,EE,FF,GG。 第1-17行

即。用户可以分配位置A1,A2,A3,B4,AA1,BB2 ...... GG17

我想验证用户在分配位置时输入的文本,以阻止他们添加HH1或A20,例如..

我能够从A-Z,1-17实现这一点,但是当验证必须超过Z(AA,BB,CC ......)时,我感到磕磕绊绊

这是我迄今为止A-Z和1-17的作品

 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";
                }
         }

我有点不知所措,因为Char不能超过一个字符而且它和++不能应用于字符串

3 个答案:

答案 0 :(得分:2)

new Regex("^[A-Z][A-G]?[1-9][0-7]?$")验证大多数组合。防止从20到97的数字有点棘手。但是使用正则表达式或者只是将字符串拆分为int.TryParse并确保数字部分是&lt; = 17。

修改 是的,它有点快,并且很脏。这个应该做的伎俩:

@"^([A-Z]|([A-G])\2)([1-9]|1[0-7])$"

使用示例:

Regex regex = new Regex(@"^([A-Z]|([A-G])\2)([1-9]|1[0-7])$");
string userInput = "AG20";
bool ok = regex.Match(userInput).Success;

答案 1 :(得分:2)

基于David在评论中所说的,为什么不简单地有一个“硬编码”的可接受值列表,因为没有那么多,只是检查任何输入的文本对这个列表?

// 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}");
    }
}

现在您只需检查此列表以进行验证:

locations.Contains("A1"); // true  
locations.Contains("BB10"); // true
locations.Contains("AF7");  // false
locations.Contains("GA10");  // false

答案 2 :(得分:0)

您只需在方法中提供maxColumn和maxRow(或作为变量传入)而不是数组或其他逻辑硬编码即可。您可以使用LINQ增强此功能,但为了清晰起见,将答案作为循环提供:

    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;
    }

更新:如果您对LINQ版本感兴趣,请点击这里:

    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;
    }