我知道如何检查这个。
正则表达式,int.parse
,tryparse
,循环。
谁能告诉我什么是最快的检查方式?
只需检查无需实际解析。
这与How do I identify if a string is a number?
的问题不同问题不仅在于识别方式。 但是关于什么是最快方法。
答案 0 :(得分:227)
bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
可能是最快的方法。
答案 1 :(得分:57)
以下是一些基于相同字符串的1000000个解析的基准测试:
更新了release
统计信息:
IsDigitsOnly: 384588
TryParse: 639583
Regex: 1329571
这是代码,看起来像IsDigitsOnly更快:
class Program
{
private static Regex regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();
string test = int.MaxValue.ToString();
int value;
watch.Start();
for(int i=0; i< 1000000; i++)
{
int.TryParse(test, out value);
}
watch.Stop();
Console.WriteLine("TryParse: "+watch.ElapsedTicks);
watch.Reset();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
IsDigitsOnly(test);
}
watch.Stop();
Console.WriteLine("IsDigitsOnly: " + watch.ElapsedTicks);
watch.Reset();
watch.Start();
for (int i = 0; i < 1000000; i++)
{
regex.IsMatch(test);
}
watch.Stop();
Console.WriteLine("Regex: " + watch.ElapsedTicks);
Console.ReadLine();
}
static bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
}
当然值得注意的是,TryParse确实允许前导/尾随空格以及特定于文化的符号。它的长度也受到限制。
答案 2 :(得分:36)
您可以使用LINQ
执行此操作 return str.All(char.IsDigit);
.All
为空字符串返回true,为空字符串返回异常。char.IsDigit
适用于所有Unicode字符。答案 3 :(得分:34)
char已经有一个IsDigit(char c),它执行此操作:
public static bool IsDigit(char c)
{
if (!char.IsLatin1(c))
return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
if ((int) c >= 48)
return (int) c <= 57;
else
return false;
}
你可以这样做:
var theString = "839278";
bool digitsOnly = theString.All(char.IsDigit);
答案 4 :(得分:18)
仅使用char
和for
代替foreach
进行一次比较,速度提高约20%:
bool isDigits(string s)
{
if (s == null || s == "") return false;
for (int i = 0; i < s.Length; i++)
if ((s[i] ^ '0') > 9)
return false;
return true;
}
用于测试的代码(总是配置文件,因为结果取决于硬件,版本,订单等):
static bool isDigitsFr(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if (s[i] < '0' || s[i] > '9') return false; return true; }
static bool isDigitsFu(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((uint)(s[i] - '0') > 9) return false; return true; }
static bool isDigitsFx(string s) { if (s == null || s == "") return false; for (int i = 0; i < s.Length; i++) if ((s[i] ^ '0') > 9) return false; return true; }
static bool isDigitsEr(string s) { if (s == null || s == "") return false; foreach (char c in s) if (c < '0' || c > '9') return false; return true; }
static bool isDigitsEu(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((uint)(c - '0') > 9) return false; return true; }
static bool isDigitsEx(string s) { if (s == null || s == "") return false; foreach (char c in s) if ((c ^ '0') > 9) return false; return true; }
static void test()
{
var w = new Stopwatch(); bool b; var s = int.MaxValue + ""; int r = 12345678*2; var ss = new SortedSet<string>(); //s = string.Concat(Enumerable.Range(0, 127).Select(i => ((char)i ^ '0') < 10 ? 1 : 0));
w.Restart(); for (int i = 0; i < r; i++) b = s.All(char.IsDigit); w.Stop(); ss.Add(w.Elapsed + ".All .IsDigit");
w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => c >= '0' && c <= '9'); w.Stop(); ss.Add(w.Elapsed + ".All <>");
w.Restart(); for (int i = 0; i < r; i++) b = s.All(c => (c ^ '0') < 10); w.Stop(); ss.Add(w.Elapsed + " .All ^");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFr(s); w.Stop(); ss.Add(w.Elapsed + " for <>");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFu(s); w.Stop(); ss.Add(w.Elapsed + " for -");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsFx(s); w.Stop(); ss.Add(w.Elapsed + " for ^");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEr(s); w.Stop(); ss.Add(w.Elapsed + " foreach <>");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEu(s); w.Stop(); ss.Add(w.Elapsed + " foreach -");
w.Restart(); for (int i = 0; i < r; i++) b = isDigitsEx(s); w.Stop(); ss.Add(w.Elapsed + " foreach ^");
MessageBox.Show(string.Join("\n", ss)); return;
}
英特尔i5-3470 @ 3.2GHz,VS 2015 .NET 4.6.1发布模式和优化启用的结果:
time method ratio
0.7776 for ^ 1.0000
0.7984 foreach - 1.0268
0.8066 foreach ^ 1.0372
0.8940 for - 1.1497
0.8976 for <> 1.1543
0.9456 foreach <> 1.2160
4.4559 .All <> 5.7303
4.7791 .All ^ 6.1458
4.8539 .All. IsDigit 6.2421
对于任何想要使用较短方法的人,请注意
.All
会产生true
for empty strings和null
字符串char.IsDigit
适用于所有Unicode characters in the Nd category int.TryParse
也允许使用白色spase和签名字符答案 5 :(得分:13)
如果您担心效果,请同时使用int.TryParse
或Regex
- 编写您自己的(简单)功能(DigitsOnly
或DigitsOnly2
,但不 DigitsOnly3
- LINQ似乎会产生很大的开销。
另外,请注意,如果字符串太长而无法“适应”int.TryParse
,则int
将失败。
这个简单的基准......
class Program {
static bool DigitsOnly(string s) {
int len = s.Length;
for (int i = 0; i < len; ++i) {
char c = s[i];
if (c < '0' || c > '9')
return false;
}
return true;
}
static bool DigitsOnly2(string s) {
foreach (char c in s) {
if (c < '0' || c > '9')
return false;
}
return true;
}
static bool DigitsOnly3(string s) {
return s.All(c => c >= '0' && c <= '9');
}
static void Main(string[] args) {
const string s1 = "916734184";
const string s2 = "916734a84";
const int iterations = 1000000;
var sw = new Stopwatch();
sw.Restart();
for (int i = 0 ; i < iterations; ++i) {
bool success = DigitsOnly(s1);
bool failure = DigitsOnly(s2);
}
sw.Stop();
Console.WriteLine(string.Format("DigitsOnly: {0}", sw.Elapsed));
sw.Restart();
for (int i = 0; i < iterations; ++i) {
bool success = DigitsOnly2(s1);
bool failure = DigitsOnly2(s2);
}
sw.Stop();
Console.WriteLine(string.Format("DigitsOnly2: {0}", sw.Elapsed));
sw.Restart();
for (int i = 0; i < iterations; ++i) {
bool success = DigitsOnly3(s1);
bool failure = DigitsOnly3(s2);
}
sw.Stop();
Console.WriteLine(string.Format("DigitsOnly3: {0}", sw.Elapsed));
sw.Restart();
for (int i = 0; i < iterations; ++i) {
int dummy;
bool success = int.TryParse(s1, out dummy);
bool failure = int.TryParse(s2, out dummy);
}
sw.Stop();
Console.WriteLine(string.Format("int.TryParse: {0}", sw.Elapsed));
sw.Restart();
var regex = new Regex("^[0-9]+$", RegexOptions.Compiled);
for (int i = 0; i < iterations; ++i) {
bool success = regex.IsMatch(s1);
bool failure = regex.IsMatch(s2);
}
sw.Stop();
Console.WriteLine(string.Format("Regex.IsMatch: {0}", sw.Elapsed));
}
}
...产生以下结果......
DigitsOnly: 00:00:00.0346094
DigitsOnly2: 00:00:00.0365220
DigitsOnly3: 00:00:00.2669425
int.TryParse: 00:00:00.3405548
Regex.IsMatch: 00:00:00.7017648
答案 6 :(得分:9)
我喜欢Linq,并且在第一次不匹配时退出,你可以这样做
string str = '0129834X33';
bool isAllDigits = !str.Any( ch=> ch < '0' || ch > '9' );
答案 7 :(得分:9)
这应该有效:
Regex.IsMatch("124", "^[0-9]+$", RegexOptions.Compiled)
int.Parse
或int.TryParse
并不总是有效,因为字符串可能包含int可容纳的更多数字。
如果您打算不止一次检查使用已编译的正则表达式是有用的 - 第一次需要更多时间,但之后会更快。
答案 8 :(得分:7)
可能最快的方法是:
let result = [{'a': 3, 'b': 2}, {'a': 4, 'c': 1}, {'a': 4, 'c': 1}];
let m = _.reduce((_.uniq(_.flattenDeep(_.map(result, i => _.keys(i))))), function (s, v) {
s[v] = _.sumBy(result, function (o) {
return o[v];
});
return s
}, {});
console.log(m); // { a: 11, b: 2, c: 2 }
注意:如果您的字符串为空(如果您不认为空为有效数字/数字),它将返回 True
答案 9 :(得分:5)
您可以在一行LINQ语句中执行此操作。好的,我意识到这不一定是最快的,所以从技术上来说不能回答这个问题,但它可能是最容易写的:
str.All(c => c >= '0' && c <= '9')
答案 10 :(得分:1)
您可以尝试使用正则表达式,方法是在C#中使用.IsMatch(string input, string pattern)
方法测试输入字符串只有数字(0-9)。
using System;
using System.Text.RegularExpression;
public namespace MyNS
{
public class MyClass
{
public void static Main(string[] args)
{
string input = Console.ReadLine();
bool containsNumber = ContainsOnlyDigits(input);
}
private bool ContainOnlyDigits (string input)
{
bool containsNumbers = true;
if (!Regex.IsMatch(input, @"/d"))
{
containsNumbers = false;
}
return containsNumbers;
}
}
}
此致
答案 11 :(得分:1)
这将完美地运作,还有许多其他方法,但这将起作用
bool IsDigitsOnly(string str)
{
if (str.Length > 0)//if contains characters
{
foreach (char c in str)//assign character to c
{
if (c < '0' || c > '9')//check if its outside digit range
return false;
}
}else//empty string
{
return false;//empty string
}
return true;//only digits
}
答案 12 :(得分:1)
这可能会来得太晚了!但是我相信它会帮助某人,就像它帮助了我。
private static bool IsDigitsOnly(string str)
{
return str.All(c => c >= '0' && c <= '9');
}
答案 13 :(得分:1)
如果是单个字符串:
if (str.All(Char.IsDigit))
{
// string contains only digits
}
如果是字符串列表:
if (lstStr.All(s => s.All(Char.IsDigit)))
{
// List of strings contains only digits
}
答案 14 :(得分:0)
试试这段代码:
bool isDigitsOnly(string str)
{
try
{
int number = Convert.ToInt32(str);
return true;
}
catch (Exception)
{
return false;
}
}
答案 15 :(得分:0)
具有空验证的功能:
public static bool IsDigitsOnly(string str)
{
return !string.IsNullOrEmpty(str) && str.All(char.IsDigit);
}
答案 16 :(得分:0)
另一种方法!
string str = "12345";
bool containsOnlyDigits = true;
try { if(Convert.ToInt32(str) < 0){ containsOnlyDigits = false; } }
catch { containsOnlyDigits = false; }
在这里,如果语句Convert.ToInt32(str)
失败,则string不只包含数字。另一种可能性是,如果字符串具有"-12345"
且已成功转换为-12345
,则将检查以确认转换后的数字不小于零。
答案 17 :(得分:-1)
非常聪明且简单的方法来检测你的字符串只包含数字或不是这样:
string s = "12fg";
if(s.All(char.IsDigit))
{
return true; // contains only digits
}
else
{
return false; // contains not only digits
}
答案 18 :(得分:-1)
public bool CheckforDigits(string x)
{
int tr;
return x.All(r=> int.TryParse(r.ToString(), out tr));
}
答案 19 :(得分:-2)
char.IsDigit(myChar)
怎么样?