C# 从带有尾随垃圾的字符串中解析整数
我需要解析一个出现在字符串开头的十进制整数 小数后可能有尾随垃圾。这需要忽略(即使它包含其他数字。) e、 g 在.NET framework中是否有内置的方法来执行此操作C# 从带有尾随垃圾的字符串中解析整数,c#,.net,parsing,C#,.net,Parsing,我需要解析一个出现在字符串开头的十进制整数 小数后可能有尾随垃圾。这需要忽略(即使它包含其他数字。) e、 g 在.NET framework中是否有内置的方法来执行此操作 int.TryParse()不适用。它允许尾随空格,但不允许其他尾随字符 这将很容易实现,但如果存在标准方法,我更愿意使用它。string s=“3-.X.-”.Trim(); string s = " 3 -.X.-".Trim(); string collectedNumber = string.empty; int i
int.TryParse()
不适用。它允许尾随空格,但不允许其他尾随字符
这将很容易实现,但如果存在标准方法,我更愿意使用它。string s=“3-.X.-”.Trim();
string s = " 3 -.X.-".Trim();
string collectedNumber = string.empty;
int i;
for (x = 0; x < s.length; x++)
{
if (int.TryParse(s[x], out i))
collectedNumber += s[x];
else
break; // not a number - that's it - get out.
}
if (int.TryParse(collectedNumber, out i))
Console.WriteLine(i);
else
Console.WriteLine("no number found");
string collectedNumber=string.empty;
int i;
对于(x=0;x
根据评论更新
我不知道你为什么不喜欢正则表达式,所以我将只发布我认为最短的解决方案
要获取第一个int:
Match match = Regex.Match(" 3 - .x. - 4", @"\d+");
if (match.Success)
Console.WriteLine(int.Parse(match.Value));
没有标准的.NET方法可以做到这一点-尽管我不会惊讶地发现VB在Microsoft.VisualBasic程序集中有一些东西(它是与.NET一起提供的,所以即使从C#使用它也不是问题) 结果是否总是非负面的(这将使事情变得更容易) 老实说,正则表达式是这里最简单的选择,但是
public static string RemoveCruftFromNumber(string text)
{
int end = 0;
// First move past leading spaces
while (end < text.Length && text[end] == ' ')
{
end++;
}
// Now move past digits
while (end < text.Length && char.IsDigit(text[end]))
{
end++;
}
return text.Substring(0, end);
}
公共静态字符串RemoveCruftFromNumber(字符串文本)
{
int end=0;
//先过前导空格
while(end
然后,您只需对
RemoveCruftFromNumber
的结果调用int.TryParse
(不要忘记整数可能太大,无法存储在int
中)。我不确定在这种情况下为什么要避免使用正则表达式
这里有一个小黑客,你可以调整到你的需要
“3-.X.-”.tocharray().FindInteger().ToList().ForEach(Console.WriteLine)
公共静态类字符扩展
{
公共静态IEnumerable FindIntegrater(此IEnumerable数组)
{
foreach(数组中的变量c)
{
如果(字符编号(c))
收益率c;
}
}
}
编辑:
对于错误的结果(以及维护开发人员:)也是如此
这里有一个修订:
public static int FindFirstInteger(this IEnumerable<char> array)
{
bool foundInteger = false;
var ints = new List<char>();
foreach (var c in array)
{
if(char.IsNumber(c))
{
foundInteger = true;
ints.Add(c);
}
else
{
if(foundInteger)
{
break;
}
}
}
string s = string.Empty;
ints.ForEach(i => s += i.ToString());
return int.Parse(s);
}
public static int FindFirstInteger(此IEnumerable数组)
{
bool foundInteger=false;
var ints=新列表();
foreach(数组中的变量c)
{
如果(字符编号(c))
{
foundInteger=true;
内加(c);
}
其他的
{
if(foundInteger)
{
打破
}
}
}
string s=string.Empty;
ints.ForEach(i=>s+=i.ToString());
返回int.Parse;
}
私有字符串GetInt(字符串s)
{
int i=0;
s=s.修剪();
而(我也不妨加上我的
string temp = " 3 .x£";
string numbersOnly = String.Empty;
int tempInt;
for (int i = 0; i < temp.Length; i++)
{
if (Int32.TryParse(Convert.ToString(temp[i]), out tempInt))
{
numbersOnly += temp[i];
}
}
Int32.TryParse(numbersOnly, out tempInt);
MessageBox.Show(tempInt.ToString());
string temp=“3.x”;
string numbersOnly=string.Empty;
int-tempInt;
对于(int i=0;i
该消息框仅用于测试目的,验证方法是否正常后将其删除。您可以使用Linq执行此操作,无需正则表达式:
public static int GetLeadingInt(string input)
{
return Int32.Parse(new string(input.Trim().TakeWhile(c => char.IsDigit(c) || c == '.').ToArray()));
}
这适用于您提供的所有示例:
string[] tests = new string[] {
"1",
" 42 ",
" 3 -.X.-",
" 2 3 4 5"
};
foreach (string test in tests)
{
Console.WriteLine("Result: " + GetLeadingInt(test));
}
这就是我在Java中的实现方式:
int parseLeadingInt(String input)
{
NumberFormat fmt = NumberFormat.getIntegerInstance();
fmt.setGroupingUsed(false);
return fmt.parse(input, new ParsePosition(0)).intValue();
}
我希望类似的东西能在.NET中实现
这是我目前使用的基于正则表达式的解决方案:
int? parseLeadingInt(string input)
{
int result = 0;
Match match = Regex.Match(input, "^[ \t]*\\d+");
if (match.Success && int.TryParse(match.Value, out result))
{
return result;
}
return null;
}
我喜欢“甜甜圈”的方法
不过,我想补充一点,char.IsDigit
和char.IsNumber
也允许使用一些unicode字符,这些字符是其他语言和脚本中的数字()。
如果只想检查数字0到9,可以使用“0123456789”.Contains(c)
三个示例实现:
要删除尾随的非数字字符:
var digits = new string(input.Trim().TakeWhile(c =>
("0123456789").Contains(c)
).ToArray());
var digits = new string(input.Trim().SkipWhile(c =>
!("0123456789").Contains(c)
).ToArray());
var digits = new string(input.Trim().Where(c =>
("0123456789").Contains(c)
).ToArray());
删除前导非数字字符:
var digits = new string(input.Trim().TakeWhile(c =>
("0123456789").Contains(c)
).ToArray());
var digits = new string(input.Trim().SkipWhile(c =>
!("0123456789").Contains(c)
).ToArray());
var digits = new string(input.Trim().Where(c =>
("0123456789").Contains(c)
).ToArray());
要删除所有非数字字符:
var digits = new string(input.Trim().TakeWhile(c =>
("0123456789").Contains(c)
).ToArray());
var digits = new string(input.Trim().SkipWhile(c =>
!("0123456789").Contains(c)
).ToArray());
var digits = new string(input.Trim().Where(c =>
("0123456789").Contains(c)
).ToArray());
当然:int.Parse(digits)
或int.TryParse(digits,out output)
这并不能真正回答您的问题(关于内置C方法),但您可以尝试逐个切掉输入字符串末尾的字符,直到int.TryParse()
将其作为有效数字接受:
for (int p = input.Length; p > 0; p--)
{
int num;
if (int.TryParse(input.Substring(0, p), out num))
return num;
}
throw new Exception("Malformed integer: " + input);
当然,如果输入
很长,这将很慢
附录(2016年3月)
在尝试每次解析之前,切掉右侧的所有非数字/非空格字符,可以加快解析速度:
for (int p = input.Length; p > 0; p--)
{
char ch;
do
{
ch = input[--p];
} while ((ch < '0' || ch > '9') && ch != ' ' && p > 0);
p++;
int num;
if (int.TryParse(input.Substring(0, p), out num))
return num;
}
throw new Exception("Malformed integer: " + input);
for(int p=input.Length;p>0;p--)
{
char ch;
做
{
ch=输入[--p];
}while((ch<'0'| ch>'9')&&ch!=''&&p>0);
p++;
int-num;
if(int.TryParse(input.Substring(0,p),out num))
返回num;
}
抛出新异常(“格式错误的整数:+input”);
我假设你讨厌正则表达式,但我认为这是他们想要解决的问题……使用正则表达式是可以的。但如果有内置函数,则更可取。是有效的“整数”字符后面总是跟空格字符还是只跟空格字符?@ChrisBD,不一定有空格。但是第一个非空格字符总是一个数字。可能的