是否有库函数来确定字符串的哪个部分是数字?

问题描述 投票:1回答:1

是否有任何库函数使用字符串的字符并将其解析为双精度字符-即使不是整个字符串都是数字-并返回使用的字符数解析结果?

[我想像是int ConsumeDouble(string text, out double value)。假设我有一个string s = "12.42;3.14",该函数将读取“ 12.42”,停在分号,将12.42写入值并返回5,因为它消耗了5个字符。

我微弱地记得C中存在类似的东西,但是我在C#中找不到类似的东西。点网框架中是否存在这样的功能?还是没有自己编写解析器并且没有正则表达式的任何方法?


上面的字符串s仅是一个示例,在我的用例中,没有明确指示我可以期望数字的位置,而不能期望数字。


如果不存在这样的功能,编写这种功能的最佳方法是什么?我考虑过使用状态机检查哪些字符属于数字,然后使用double.Parse()对其进行解析。
c# string-parsing
1个回答
2
投票

假设效率不是一个太大的问题,并且假设您始终希望数字从字符串的开始处开始而不是从中间开始:

public static (double result, int consumed) ParseLongestNumber(string s)
{
    for (int n = s.Length; n > 0; --n)
    {
        string t = s.Substring(0, n);

        if (double.TryParse(t, out var r))
            return (r, n);
    }

    return (double.NaN, 0);
}

这应处理所有数字格式,例如ParseLongestNumber("-1.42e3;3.14")将返回(-1420, 7)

如果无法解析数字,它将返回(NaN, 0)

((注意:您并不是说您使用的是旧版本的C#,如果您使用的是C#,则必须通过out参数或显式Tuple返回结果,而不是通过新样式返回)元组。)

一种可能的优化是找到最后一个可能的数字字符,然后仅对其进行解析:

public static (double result, int consumed) ParseLongestNumber(string s)
{
    const string NUMBER_CHARS = "+-.,_e0123456789";

    int n = 0;

    while (n < s.Length)
        if (NUMBER_CHARS.IndexOf(s[n]) < 0)
            break;
        else
            ++n;

    for (; n > 0; --n)
    {
        string t = s.Substring(0, n);

        if (double.TryParse(t, out var r))
            return (r, n);
    }

    return (double.NaN, 0);
}

此优化是否实际上有用,只能通过经验测试来确定。

© www.soinside.com 2019 - 2024. All rights reserved.