如何在 C# 中查找字符串值采用指数格式

本文关键字:指数 格式 字符串 查找 | 更新日期: 2023-09-27 17:55:58

我想找出字符串是否具有指数格式。 目前我正在检查如下。

var s = "1.23E+04";
var hasExponential = s.Contains("E");

但我知道这不是正确的方法。那么任何人都可以指导正确和最快的方法来达到我的要求吗?

如何在 C# 中查找字符串值采用指数格式

如果你还想确保它真的是一个数字,而不仅仅是一个带有"E"的字符串,也许这样的函数会有所帮助。 逻辑仍然很简单。

private bool IsExponentialFormat(string str)
{
    double dummy;
    return (str.Contains("E") || str.Contains("e")) && double.TryParse(str, out dummy);
}

尝试使用正则表达式?

string s = "1.23E+04";
string pattern = @"^'d{1}.'d+(E'+)'d+$";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
bool hasExponential = rgx.IsMatch(s);

你总是可以在e上分裂。或者使用 double.TryParse .两者都工作得很好。(我敢打赌,有效ParseExponential2更快,而无效ParseExponential1可能会更快。

public static void _Main(string[] args)
{
    string[] exponentials = new string[] { "1.23E+4", "1.23E+04", "1.23e+4", "1.23", "1.23e+4e+4", "abce+def", "1.23E-04" };
    for (int i = 0; i < exponentials.Length; i++)
        Console.WriteLine("Input: {0}; Result 1: {1}; Result 2: {2}; Result 3: {3}", exponentials[i], (ParseExponential1(exponentials[i]) ?? 0), (ParseExponential2(exponentials[i]) ?? 0), (ParseExponential3(exponentials[i]) ?? 0));
}
public static double? ParseExponential1(string input)
{
    if (input.Contains("e") || input.Contains("E"))
    {
        string[] inputSplit = input.Split(new char[] { 'e', 'E' });
        if (inputSplit.Length == 2) // If there were not two elements split out, it's an invalid exponential.
        {
            double left = 0;
            int right = 0;
            if (double.TryParse(inputSplit[0], out left) && int.TryParse(inputSplit[1], out right) // Parse the values
                && (left >= -5.0d && left <= 5.0d && right >= -324) // Check that the values are within the range of a double, this is the minimum.
                && (left >= -1.7d && left <= 1.7d && right <= 308)) // Check that the values are within the range of a double, this is the maximum.
            {
                double result = 0;
                if (double.TryParse(input, out result))
                    return result;
            }
        }
    }
    return null;
}
public static double? ParseExponential2(string input)
{
    if (input.Contains("e") || input.Contains("E"))
    {
        double result = 0;
        if (double.TryParse(input, out result))
            return result;
    }
    return null;
}
public static double? ParseExponential3(string input)
{
    double result = 0;
    if (double.TryParse(input, out result))
        return result;
    return null;
}

如果ParseExponential1ParseExponential2ParseExponential3返回null,则无效。这也允许您同时解析它并获取指示的值。

ParseExponential3的唯一问题是,如果它们不是指数,它也将返回有效数字。(即,对于1.23情况,它将返回1.23

您还可以删除double范围的检查。他们只是为了完整而存在。

另外,为了证明一个观点,我只是用下面的代码运行了一个基准测试,nevermoi 的另一个答案中的Regex选项需要500msexponentials 数组上运行 100,000 次,ParseExponential1选项需要547msParseExponential2选项317ms。斯坦的方法花了346ms.最后,最快的是我在134msParseExponential3方法。

string[] exponentials = new string[] { "1.23E+4", "1.23E+04", "1.23e+4", "1.23", "1.23e+4e+4", "abce+def", "1.23E-04" };
Stopwatch sw = new Stopwatch();
sw.Start();
for (int round = 0; round < 100000; round++)
    for (int i = 0; i < exponentials.Length; i++)
        ParseExponential1(exponentials[i]);
sw.Stop();
Console.WriteLine("Benchmark 1 (ParseExponential1) complete: {0}ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int round = 0; round < 100000; round++)
    for (int i = 0; i < exponentials.Length; i++)
        ParseExponential2(exponentials[i]);
sw.Stop();
Console.WriteLine("Benchmark 2 (ParseExponential2) complete: {0}ms", sw.ElapsedMilliseconds);
sw.Reset();
string pattern = @"^'d{1}.'d+(E'+)'d+$";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
sw.Start();
for (int round = 0; round < 100000; round++)
    for (int i = 0; i < exponentials.Length; i++)
        rgx.IsMatch(exponentials[i]);
sw.Stop();
Console.WriteLine("Benchmark 3 (Regex Parse) complete: {0}ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int round = 0; round < 100000; round++)
    for (int i = 0; i < exponentials.Length; i++)
        IsExponentialFormat(exponentials[i]);
sw.Stop();
Console.WriteLine("Benchmark 4 (IsExponentialFormat) complete: {0}ms", sw.ElapsedMilliseconds);
sw.Start();
for (int round = 0; round < 100000; round++)
    for (int i = 0; i < exponentials.Length; i++)
        ParseExponential3(exponentials[i]);
sw.Stop();
Console.WriteLine("Benchmark 5 (ParseExponential3) complete: {0}ms", sw.ElapsedMilliseconds);

并添加了以下方法:

private static bool IsExponentialFormat(string str)
{
    double dummy;
    return (str.Contains("E") || str.Contains("e")) && double.TryParse(str, out dummy);
}