0

我有一个可以输入的字符串{n}d {n}h {n}m {n}swhere{n}是一个整数,表示天数、小时数、分钟数、秒数。我如何{n}从字符串中提取这个数字?

用户不必输入所有 4 - d、h、m、s。他只能输入 4d 表示 4 天或 5h 2s 表示 5 小时 2 秒。

这就是我所拥有的。绝对应该有更好的方法来做到这一点。此外,并不涵盖所有情况。

int d; int m; int h; int sec;
string [] split = textBox3.Text.Split(new Char [] {' ', ','});
List<string> myCollection = new List<string>();

foreach (string s in split)
{
    d = Convert.ToInt32(s.Substring(0,s.Length-1));
    h = Convert.ToInt32(split[1].Substring(1));
    m = Convert.ToInt32(split[2].Substring(1));
    sec = Convert.ToInt32(split[3].Substring(1));
}
dt  =new TimeSpan(h,m,s);
4

5 回答 5

3

如果天、小时、分钟和秒的顺序是固定的,那么您可以使用正则表达式:

string input = textBox3.Text.Trim();
Match match = Regex.Match(input,
    "^" +
    "((?<d>[0-9]+)d)? *" +
    "((?<h>[0-9]+)h)? *" +
    "((?<m>[0-9]+)m)? *" +
    "((?<s>[0-9]+)s)?" +
    "$",
    RegexOptions.ExplicitCapture);

if (match.Success)
{
    int d, h, m, s;
    Int32.TryParse(match.Groups["d"].Value, out d);
    Int32.TryParse(match.Groups["h"].Value, out h);
    Int32.TryParse(match.Groups["m"].Value, out m);
    Int32.TryParse(match.Groups["s"].Value, out s);
    // ...
}
else
{
    // Invalid input.
}
于 2012-06-24T20:28:58.143 回答
0

编写自定义解析器 - 使用状态机来确定字符串中的每个部分到底是什么。

这个想法是迭代字符串中的每个字符并根据它是什么来改变状态。因此,您将有一个Number状态和Day, Month, Hour,Seconds状态SpaceStart End状态。

于 2012-06-24T20:10:36.493 回答
0

一种方法可能是使用sscanf(),这很容易做到这一点。我在本文中用C# 实现了这个函数的一个版本。

如果您需要更好地处理潜在的语法错误,那么您只需实现自己的解析器。我会通过一个一个地检查每个角色来做到这一点。

于 2012-06-24T20:11:30.393 回答
0

这里有多种选择。您可以尝试使用 TimeSpan.TryParse 函数,但这需要不同的输入格式。另一种方法是将字符串拆分为空格并遍历每个部分。这样做时,您可以检查该部分是否包含dhs等,并将值提取到所需的变量中。您甚至可以使用 RegEx 来解析字符串。下面是一个基于迭代的例子:

    static void Main(string[] args)
    {
        Console.WriteLine("Enter the desired Timespan");
        string s = Console.ReadLine();

        //ToDo: Make sure that s has the desired format

        //Get the TimeSpan, create a new list when the string does not contain a whitespace.
        TimeSpan span = s.Contains(' ') ? extractTimeSpan(new List<string>(s.Split(' '))) : extractTimeSpan(new List<string>{s});

        Console.WriteLine(span.ToString());

        Console.ReadLine();
    }

    static private TimeSpan extractTimeSpan(List<string> parts)
    {
        //We will add our extracted values to this timespan
        TimeSpan extracted = new TimeSpan();

        foreach (string s in parts)
        {
            if (s.Length > 0)
            {
                //Extract the last character of the string
                char last = s[s.Length - 1];

                //extract the value
                int value;
                Int32.TryParse(s.Substring(0, s.Length - 1), out value);

                switch (last)
                {
                    case 'd':
                        extracted = extracted.Add(new TimeSpan(value,0,0,0));
                        break;
                    case 'h':
                        extracted = extracted.Add(new TimeSpan(value, 0, 0));
                        break;
                    case 'm':
                        extracted = extracted.Add(new TimeSpan(0, value, 0));
                        break;
                    case 's':
                        extracted = extracted.Add(new TimeSpan(0, 0, value));
                        break;
                    default:
                        throw new Exception("Wrong input format");
                }
            }
            else
            {
                throw new Exception("Wrong input format");
            }
        }

        return extr
于 2012-06-24T20:16:31.390 回答
0

您可以稍微改进您的方法

int d = 0;
int m = 0;
int h = 0;
int s = 0;

// Because of the "params" keyword, "new char[]" can be dropped.
string [] parts = textBox3.Text.Split(' ', ',');

foreach (string part in parts)
{
    char type = part[part.Length - 1];
    int value = Convert.ToInt32(part.Substring(0, part.Length - 1));
    switch (type) {
        case 'd':
            d = value;
            break;
        case 'h':
            h = value;
            break;
        case 'm':
            m = value;
            break;
        case 's':
            s = value;
            break;
    }
}

现在您已经拥有了完整的非缺失部件集。缺失的部分还在0。您可以将值转换TimeSpan

var ts = TimeSpan.FromSeconds(60 * (60 * (24 * d + h) + m) + s);

这涵盖了所有情况!

于 2012-06-24T20:38:05.567 回答