查找字符串中的各种数字

时间:2012-05-27 12:05:17

标签: c# string numbers replace

例如,字符串可以包含整数,浮点数和十六进制数。

“这个字符串可以有-345和57,也可以有35.4656或一个微妙的0xF46434以及更多”

我可以用什么来在C#中找到这些数字?

4 个答案:

答案 0 :(得分:3)

沿着这些方向使用一些东西:(我自己写的,所以我不会说它对于你想找到的任何类型的数字都是包罗万象的,但它适用于你的例子)

var str = "123 This a string than can have -345 and 57 and could also have 35.4656 or a subtle 0XF46434 and more like -0xf46434";
var a = Regex.Matches(str, @"(?<=(^|[^a-zA-Z0-9_^]))(-?\d+(\.\d+)?|-?0[xX][0-9A-Fa-f]+)(?=([^a-zA-Z0-9_]|$))");
foreach (Match match in a)
{
    //do something
}

正则表达式似乎是一种只写的语言,(即难以阅读),所以我将其分解,以便您理解:(?<=(^|[^a-zA-Z0-9_^]))是一个用字边界来打破它的后视。我无法使用\b,因为它会将-视为边界字符,因此它只会匹配345而不是-345-?\d+(\.\d+)?匹配十进制数字,可选地为负数,可选地为小数位数。 -?0[xX][0-9A-Fa-f]+匹配十六进制数字,不区分大小写,可选地为负数。最后,(?=([^a-zA-Z0-9_]|$))是一个先行,再次作为单词边界。请注意,在第一个边界中,我允许字符串的开头,这里我允许字符串的结尾。

答案 1 :(得分:2)

尝试将每个单词解析为doublereturn array double。{/ p>

以下是从[{1}}获取array double的方法:

string

有关double[] GetNumbers(string str) { double num; List<double> l = new List<double>(); foreach (string s in str.Split(' ')) { bool isNum = double.TryParse(s, out num); if (isNum) { l.Add(num); } } return l.ToArray(); } here的更多信息。

答案 2 :(得分:1)

鉴于您的输入,此表达式匹配那里的每个数字

string line = "This a string than can have " + 
                      "-345 and 57 and could also have 35.4656 " +
                      "or a subtle 0xF46434 and more";

Regex r = new Regex(@"(-?0[Xx][A-Fa-f0-9]+|-?\d+\.\d+|-?\d+)");
var m = r.Matches(line);
foreach(Match h in m)
    Console.WriteLine(h.ToString());

编辑:对于替换,您使用带有MatchEvaluator重载的Replace方法

string result = r.Replace(line, new MatchEvaluator(replacementMethod));
public string replacementMethod(Match match)
{
   return "?????";
}

解释正则表达式

首先,序列"(pattern1|pattern2|pattern3)"意味着我们在字符串中有三种可能的模式。其中一个足以匹配

第一个模式-?0[Xx][A-Fa-f0-9]+表示可选的减号,后跟一个零,后跟一个X或x字符,后跟一系列一个或多个字符,范围为​​A-F a-f或0-9

第二个模式-?\d+\.\d+表示一个可选的减号,后跟一系列1个或更多个数字,后跟小数点后跟一系列1个或更多个数字

第三种模式-?\d+表示可选的减号,后跟一系列1位或更多位数。

模式序列至关重要。如果你反转模式并在十进制模式之前放置整数匹配,结果将是错误的。

答案 3 :(得分:1)

除了regex,它往往有自己的问题,你可以建立一个状态机来进行处理。您可以决定机器将接受哪些输入作为“数字”。与正则表达式不同,状态机具有可预测的良好性能,并且还会为您提供可预测的结果(而正则表达式有时可以匹配相当令人惊讶的事情)。

当你想到它时,这并不是那么困难。状态相当少,您可以明确定义特殊情况。

编辑:以下是作为对评论的回复的编辑 在.NET中,Regex实现为NFA(Nontdeterminisitc有限自动机)。一方面,它是一个非常强大的解析器,但另一方面,它有时候backtrack可能比它应该更多。当您接受不安全的输入(来自用户的输入,几乎可以是任何东西)时尤其如此。虽然我不确定你将使用什么样的Regex表达式来解析结果,但几乎任何东西都可以引起性能损失。虽然在大多数情况下性能不是问题,但Regex性能可以随输入呈指数级增长。这意味着,在某些情况下,它确实可以成为瓶颈。而且是一个相当意想不到的。

正则表达式的贪婪性质产生的另一个潜在问题是,有时它可以匹配意想不到的事物。您可能会使用相同的Regex表达式几天,它可能正常工作,等待被解析的字符的正确组合被解析,并且您最终会将垃圾写入数据库。


通过状态机,我的意思是使用确定性有限自动机或类似的东西来解析输入。我会告诉你我的意思。这是一个小的DFA,用于解析字符串中的正十进制整数或浮点数。我很确定你可以使用像ANTLR这样的框架来构建DFA,不过我确信周围也有不那么强大的东西。