如何使用 TakeWhile 进行投射

Ema*_*ser 1 c# parsing casting

我有一个里面有数字的字符串,我想将其中的第一个数字取出为双精度数。(例如"abc1.23,efg4.56"=> 1.23

我目前正在做的是这样的:

static double trimPriceResponse(string trimString)
    {
        double resultantDouble = new double();
        if (trimString.TakeWhile(Char.IsDigit).ToString().Length != 0)
        {
            resultantDouble = Double.Parse(String.Join("", Convert.ToChar(trimString.TakeWhile(Char.IsDigit))));
        }
        else
        {
            trimString.Remove(0, 1);
            trimPriceResponse(trimString);
        }
        return resultantDouble;
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,当我这样做时,我收到此运行时错误: InvalidCastException:无法将类型为 'd__247`1[System.Char]' 的对象转换为类型为 'System.IConvertible'。

我之前曾尝试使用以下方法转换为字符串:

trimString.TakeWhile(Char.IsDigit).ToString().Length
Run Code Online (Sandbox Code Playgroud)

但它返回一个错误,指出字符串的格式不正确。

有没有更好的方法从字符串中获取双精度值或使上述工作起作用?

Eti*_*tel 5

这不会给你你想要的,它只会打印任何内部迭代器类的类型TakeWhile这不会给你你想要的,它只会打印实现返回的

\n
trimString.TakeWhile(char.IsDigit).ToString()\n
Run Code Online (Sandbox Code Playgroud)\n

TakeWhile返回一个IEnumerable<char>,即字符序列。要从中获取字符串,您必须连接这些字符:

\n
string.Concat(trimString.TakeWhile(char.IsDigit));\n
Run Code Online (Sandbox Code Playgroud)\n

而且,上面的代码还会为您提供一个带有输入的空字符串"abc1.23,efg4.56"。这是因为它会接受字符,而它们是数字,并且字符串以字母开头,所以它会立即停止。您首先必须跳过非数字,然后获取数字:

\n
string.Concat(trimString.SkipWhile(c => !char.IsDigit(c)).TakeWhile(char.IsDigit));\n
Run Code Online (Sandbox Code Playgroud)\n

但即便如此,这也不理想,因为你的数字是浮点数,而不是整数,所以它们有小数分隔符:

\n
string.Concat(trimString.SkipWhile(c => !char.IsDigit(c)).TakeWhile(c =>\xc2\xa0char.IsDigit(c) || c == '.'));\n
Run Code Online (Sandbox Code Playgroud)\n

但任何混乱的数字和句点都不是有效的数字。啊!\n这变得很笨拙。

\n

由于您真正想要做的是在文本中找到一种模式(一个或多个数字,可选地后跟一个句点,然后是一个或多个数字),我建议您只使用正则表达式,因为这是它们的目的。然后,由于正则表达式匹配仍然是文本,因此您必须解析它们,但至少可以保证解析成功(假设您使用不变的区域性来确保小数点分隔符句点)。

\n
var match = Regex.Match(trimString, @"\\d+(\\.\\d+)?");\nif(match.Success)\n{\n   resultantDouble = double.Parse(match.Value, CultureInfo.InvariantCulture);\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

顺便说一下,里面有一股代码味道:

\n
trimString.Remove(0, 1);\ntrimPriceResponse(trimString);\n
Run Code Online (Sandbox Code Playgroud)\n

C# 字符串是不可变的,trimString.Remove(0, 1)实际上并不修改trimString,它返回一个删除了第一个字符的新字符串,因此整行没有任何效果,因为您没有使用 的返回值Remove。你的意思可能是这样的:

\n
trimPriceResponse(trimString.Remove(0, 1));\n
Run Code Online (Sandbox Code Playgroud)\n