C# 确定可能包含字母和数字字符的数字范围

C# 确定可能包含字母和数字字符的数字范围,c#,winforms,C#,Winforms,我甚至不知道如何表达这个问题,所以我提前道歉。我有一张我们QA使用的表格。它需要输入序列号——很多(有时数百)。我在表单上有两个文本框,分别表示范围内的下限和上限数字(不一定要这样,但这是我最好的猜测)。如果它只是整数(见下面的代码),我知道怎么做,但这不是唯一的格式。格式的示例可能包括日期代码(“170508/1234”)或字母字符(ABC1234)。有多种格式,但在每种情况下,我都希望找到最后一组数字的范围(通常是最后四位数字,如“170508/1234 170508/1235…和ABC12

我甚至不知道如何表达这个问题,所以我提前道歉。我有一张我们QA使用的表格。它需要输入序列号——很多(有时数百)。我在表单上有两个文本框,分别表示范围内的下限和上限数字(不一定要这样,但这是我最好的猜测)。如果它只是整数(见下面的代码),我知道怎么做,但这不是唯一的格式。格式的示例可能包括日期代码(“170508/1234”)或字母字符(ABC1234)。有多种格式,但在每种情况下,我都希望找到最后一组数字的范围(通常是最后四位数字,如“170508/1234 170508/1235…和ABC1234 ABC1235…不排除1234 1235…”)。 先谢谢你

 private void btnSN_Click(object sender, EventArgs e)
    {
        int from = Convert.ToInt32(txtSnStart.Text.Trim());
        int to = Convert.ToInt32(txtSnEnd.Text.Trim());

        for (int i = from; i <= to; i++) 


        {

           txtSN.Text +=  i.ToString() +" ";
        } 
private void btnSN\u单击(对象发送方,事件参数e)
{
int from=Convert.ToInt32(txtSnStart.Text.Trim());
int-to=Convert.ToInt32(txtsend.Text.Trim());

对于(int i=from;i您可以使用RexEx进行此操作,下面的正则表达式应匹配末尾的任意位数:

(\d+)$
以下是修改后的代码:

// find the group of digits at end of entered text
var fromMatch = Regex.Match(txtSnStart.Text.Trim(), @"(\d+)$");
int from = Convert.ToInt32(fromMatch.Groups[1].Value);

// strip the matched digit group from entered text to get the prefix
string prefix = txtSnStart.Text.Trim().SubString(0, txtSnStart.Text.Trim().LastIndexOf(from.ToString()));

var toMatch = Regex.Match(txtSnEnd.Text.Trim(), @"(\d+)$");
int to = Convert.ToInt32(toMatch.Groups[1].Value);

for (int i = from; i <= to; i++)
{
    // combine the prefix and range value
    txtSN.Text += string.Format("{0}{1} ", prefix, i.ToString());
}
//在输入的文本末尾查找数字组
var fromMatch=Regex.Match(txtSnStart.Text.Trim(),@“(\d+)$”;
int from=Convert.ToInt32(frommach.Groups[1].Value);
//从输入的文本中删除匹配的数字组以获取前缀
字符串前缀=txtSnStart.Text.Trim().SubString(0,txtSnStart.Text.Trim().LastIndexOf(from.ToString());
var toMatch=Regex.Match(txtsend.Text.Trim(),@“(\d+)$”;
int-to=Convert.ToInt32(toMatch.Groups[1].Value);

对于(int i=from;i您可以使用RexEx进行此操作,下面的正则表达式应匹配末尾的任意位数:

(\d+)$
以下是修改后的代码:

// find the group of digits at end of entered text
var fromMatch = Regex.Match(txtSnStart.Text.Trim(), @"(\d+)$");
int from = Convert.ToInt32(fromMatch.Groups[1].Value);

// strip the matched digit group from entered text to get the prefix
string prefix = txtSnStart.Text.Trim().SubString(0, txtSnStart.Text.Trim().LastIndexOf(from.ToString()));

var toMatch = Regex.Match(txtSnEnd.Text.Trim(), @"(\d+)$");
int to = Convert.ToInt32(toMatch.Groups[1].Value);

for (int i = from; i <= to; i++)
{
    // combine the prefix and range value
    txtSN.Text += string.Format("{0}{1} ", prefix, i.ToString());
}
//在输入的文本末尾查找数字组
var fromMatch=Regex.Match(txtSnStart.Text.Trim(),@“(\d+)$”;
int from=Convert.ToInt32(frommach.Groups[1].Value);
//从输入的文本中删除匹配的数字组以获取前缀
字符串前缀=txtSnStart.Text.Trim().SubString(0,txtSnStart.Text.Trim().LastIndexOf(from.ToString());
var toMatch=Regex.Match(txtsend.Text.Trim(),@“(\d+)$”;
int-to=Convert.ToInt32(toMatch.Groups[1].Value);

对于(inti=from;i来说,如果你把它分成更小的部分,这个问题就会变得更容易

一旦问题的一小部分变得更加复杂,这将变得特别重要

输入是一个前缀、一个开始范围的数字和一个结束范围的数字。鉴于此,下面是一个类,该类具有返回这些字符串的函数:

public class StringRangeCreator
{
    public IEnumerable<string> CreateStringRange(
        string prefix, int rangeStart, int rangeEnd)
    {
        if (rangeStart > rangeEnd) throw new ArgumentException(
             $"{nameof(rangeStart)} cannot be greater than {nameof(rangeEnd)}");
        return Enumerable.Range(rangeStart, (rangeEnd-rangeStart) + 1)
            .Select(n => prefix + n);
    }
}
但是如果这些是序列号,那么你可能不想要ABC8,ABC9,ABC10。你可能想要ABC08,ABC09,ABC10。所有长度都一样

这是一个修改过的类。我在猜测预期的行为可能是什么。它允许您指定可选的最小位数,以便您可以相应地填充:

public class StringRangeCreator
{
    public IEnumerable<string> CreateStringRange(
        string prefix, int rangeStart, int rangeEnd, int minimumDigits = 1)
    {
        if (rangeStart > rangeEnd) throw new ArgumentException(
             $"{nameof(rangeStart)} cannot be greater than {nameof(rangeEnd)}");
        return Enumerable.Range(rangeStart, (rangeEnd-rangeStart) + 1)
            .Select(n => prefix + n.ToString("0").PadLeft(minimumDigits, '0'));
    }
}
您可能需要考虑的其他一些情况是负数或非常大的范围

现在,创建结果集的问题被划分为一个类,该类具有简单的输入和输出,您可以进行测试,剩下的是从表单中获取输入并将其分解为这些输入。这可能包括确保两个字符串具有相同的前缀,以及确保字符串的最后部分是数字

但是,一旦不是一个大方法中的全部内容,整个过程就会简单一些。这也使得当你意识到你希望它如何工作时,更容易进行更改。验证你的输入可以是一个步骤,然后获得结果可以是另一个步骤


单元测试很有帮助,因为你不想调试整个程序来查看它是否工作。
Enumerable.Range
没有像我想象的那样工作,所以我必须修复一个bug。通过单元测试很容易找到并修复。如果我必须运行整个应用程序,然后在调试器中逐步调试它,那就更难了。

这个专业版如果你把它分成更小的碎片,问题就会变得更容易

一旦问题的一小部分变得更加复杂,这将变得特别重要

输入是一个前缀、一个开始范围的数字和一个结束范围的数字。鉴于此,下面是一个类,该类具有返回这些字符串的函数:

public class StringRangeCreator
{
    public IEnumerable<string> CreateStringRange(
        string prefix, int rangeStart, int rangeEnd)
    {
        if (rangeStart > rangeEnd) throw new ArgumentException(
             $"{nameof(rangeStart)} cannot be greater than {nameof(rangeEnd)}");
        return Enumerable.Range(rangeStart, (rangeEnd-rangeStart) + 1)
            .Select(n => prefix + n);
    }
}
但是如果这些是序列号,那么你可能不想要ABC8,ABC9,ABC10。你可能想要ABC08,ABC09,ABC10。所有长度都一样

这是一个修改过的类。我在猜测预期的行为可能是什么。它允许您指定可选的最小位数,以便您可以相应地填充:

public class StringRangeCreator
{
    public IEnumerable<string> CreateStringRange(
        string prefix, int rangeStart, int rangeEnd, int minimumDigits = 1)
    {
        if (rangeStart > rangeEnd) throw new ArgumentException(
             $"{nameof(rangeStart)} cannot be greater than {nameof(rangeEnd)}");
        return Enumerable.Range(rangeStart, (rangeEnd-rangeStart) + 1)
            .Select(n => prefix + n.ToString("0").PadLeft(minimumDigits, '0'));
    }
}
您可能需要考虑的其他一些情况是负数或非常大的范围

现在,创建结果集的问题被划分为一个类,该类具有简单的输入和输出,您可以进行测试,剩下的是从表单中获取输入并将其分解为这些输入。这可能包括确保两个字符串具有相同的前缀,以及确保字符串的最后部分是数字

但是,一旦不是一个大方法中的全部内容,整个过程就会简单一些。这也使得当你意识到你希望它如何工作时,更容易进行更改。验证你的输入可以是一个步骤,然后获得结果可以是另一个步骤


单元测试很有帮助,因为你不想调试整个程序来查看它是否工作。
Enumerable.Range
没有像我想象的那样工作,所以我必须修复一个bug。通过单元测试很容易找到并修复。如果我必须运行整个应用程序,然后在调试器中逐步完成它,那就更难了。

谢谢-al大部分都在那里!唯一的一件事是(我很抱歉没有说清楚),我需要它来保留格式