我正在开发一个接受数字字符串作为输入的WinForms应用程序。如果我的用户输入了连续的数字范围,他/她可以使用如下的速记符号表示该范围:
12[3-5]5550[000-100]
使用该示例,我需要将该字符串扩展为它包含的整个数字范围,如下所示:
1235550000
1235550001
1235550002
..........
1235550100
1245550000
1245550001
1245550002
..........
1245550100
1255550000
1255550001
1255550002
..........
1255550100
除0-9外,字符串只包含[, - 和],它们是用于表示范围的字符。作为将示例字符串扩展为单个数字的过程的一部分,我也想验证字符串。例如,必须有相同数量的[和]字符。在括号内,范围中的第一个数字必须小于范围中的第二个数字。这些类型的东西。
是否存在执行此类字符串操作的现有模式?
答案 0 :(得分:5)
.net中没有内置的库,您可以使用。考虑到您也需要验证,您的任务非常复杂。我已经根据您的初始输入创建了一个用于生成字符串的小解决方案。请注意,这不是生产代码,我省略了一些检查。这段代码只显示了如何完成它的一种可行方式,并且可以批评。 Token
表示字符串的每个逻辑部分,在您的情况下,它是文字或范围说明符。
class Token
{
public string Value { get; set; }
public IEnumerable<string> GetAllValues()
{
if(IsRange(Value))
{
var rangeValues = Value.Split(new[] {'[', '-', ']'}, StringSplitOptions.RemoveEmptyEntries);
//numeric format defines minimal string length. [01-10] will have numericFormat = "{0:00}"
string numericFormat = CreateNumericFormat(rangeValues.ElementAt(0).Length);
int[] ranges = rangeValues.Select(val => int.Parse(val)).ToArray();
foreach (var val in GetRange(ranges[0], ranges[1]))
yield return string.Format(numericFormat, val);
}
else
{
yield return Value;
}
}
//validation is ommited
private bool IsRange(string val)
{
return Value.Contains("-");
}
private string CreateNumericFormat(int minimalLength)
{
return "{0:"+new string('0', minimalLength)+"}";
}
private IEnumerable<int> GetRange(int minValue, int maxValue)
{
return Enumerable.Range(minValue, maxValue - minValue + 1);
}
}
现在使用非常简单:
var initial = "12[05-10]3[008-010]";
var regularExp = @"\[\s*\d+\s*-\s*\d+\s*\]|\d+";
List<Token> tokens = new List<Token>();
foreach (Match match in Regex.Matches(initial , regularExp ))
{
tokens.Add(new Token {Value = match.Value});
}
IEnumerable<string> result = new []{""};//empty source for start
foreach(var token in tokens)
{
result = from v1 in result
from v2 in token.GetAllValues()
select v1 + v2;
}
//Dump is LinqPad specific call
result.Dump();
打印:
12053008
12053009
12053010
12063008
12063009
12063010
12073008
12073009
12073010
12083008
12083009
12083010
12093008
12093009
12093010
12103008
12103009
12103010
答案 1 :(得分:2)
解决方案可分为两部分:
答案 2 :(得分:1)
是否存在执行此类字符串操作的现有模式?
不,没有。
您需要为此构建自己的解析器 - 它需要考虑字符串中的位置,并且您需要决定如何表示此结构 - 取决于用法(整数列表可能不会如果列表太长且值不能由int
或long
表示,则可以正常工作。