解析字符串的整数部分

时间:2012-06-24 20:07:31

标签: c#

我有一个字符串,可以输入为{n}d {n}h {n}m {n}s,其中{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);

5 个答案:

答案 0 :(得分: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.
}

答案 1 :(得分:0)

编写自定义解析器 - 使用状态机确定字符串中每个部分的确切内容。

这个想法是迭代字符串中的每个字符并根据它改变状态。因此,您将拥有Number州和DayMonthHourSeconds州,SpaceStart { {1}}州。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这里有各种选择。您可以尝试使用TimeSpan.TryParse函数,但这需要不同的输入格式。另一种方法是将字符串拆分为空白并迭代每个部分。在执行此操作时,您可以检查该部件是否包含 d h s 等,并将值提取到所需的变量中。您甚至可以使用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

答案 4 :(得分: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);

这涵盖了所有情况!