如何在 C# 中查找指数格式的字符串值?
How to find string value is in exponential format in C#?
我想确定字符串是否具有指数格式。目前我正在检查如下。
var s = "1.23E+04";
var hasExponential = s.Contains("E");
但我知道这不是正确的方法。那么谁能指导正确和最快的方法来实现我的要求?
尝试使用正则表达式?
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' 的字符串,也许这样的函数会有所帮助。逻辑仍然很简单。
private bool IsExponentialFormat(string str)
{
double dummy;
return (str.Contains("E") || str.Contains("e")) && double.TryParse(str, out dummy);
}
你总是可以在 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;
}
如果ParseExponential1
、ParseExponential2
或ParseExponential3
returns null
则无效。这也允许您同时解析它并获得指示的值。
ParseExponential3
的唯一问题是如果数字不是指数,它也会 return 有效数字。 (即,对于 1.23
情况,它将 return 1.23
。)
您还可以删除 double
运行ge 的检查。它们只是为了完整性。
此外,为了证明一点,我只是 运行 下面代码的基准测试,而 nevermoi 的另一个答案中的 Regex
选项将 500ms
变为 运行 对 exponentials
数组执行 100,000 次,ParseExponential1
选项占用 547ms
,ParseExponential2
选项占用 317ms
。 sstan 的方法用了 346ms
。最后,最快的是我在 134ms
的 ParseExponential3
方法。
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);
}
我想确定字符串是否具有指数格式。目前我正在检查如下。
var s = "1.23E+04";
var hasExponential = s.Contains("E");
但我知道这不是正确的方法。那么谁能指导正确和最快的方法来实现我的要求?
尝试使用正则表达式?
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' 的字符串,也许这样的函数会有所帮助。逻辑仍然很简单。
private bool IsExponentialFormat(string str)
{
double dummy;
return (str.Contains("E") || str.Contains("e")) && double.TryParse(str, out dummy);
}
你总是可以在 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;
}
如果ParseExponential1
、ParseExponential2
或ParseExponential3
returns null
则无效。这也允许您同时解析它并获得指示的值。
ParseExponential3
的唯一问题是如果数字不是指数,它也会 return 有效数字。 (即,对于 1.23
情况,它将 return 1.23
。)
您还可以删除 double
运行ge 的检查。它们只是为了完整性。
此外,为了证明一点,我只是 运行 下面代码的基准测试,而 nevermoi 的另一个答案中的 Regex
选项将 500ms
变为 运行 对 exponentials
数组执行 100,000 次,ParseExponential1
选项占用 547ms
,ParseExponential2
选项占用 317ms
。 sstan 的方法用了 346ms
。最后,最快的是我在 134ms
的 ParseExponential3
方法。
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);
}