从文本中分割数字和保持文本的最佳方法

时间:2018-04-06 10:38:05

标签: c# regex

我有一个文本文件。其中一列包含一个包含文本和数字的字段。

我正在试图找出分割数字和文字的最佳方法。

以下是该字段中典型值的示例。

  

.2700 Aqr sh./Tgt sh。

     

USD 2.4700 / Tgt sh。

目前我正在使用Split功能(下面的代码),但感觉可能有更聪明的方法。

我的假设是文本中只有一个数字(我99%肯定是这种情况)但是我只看到了一些例子,所以我的代码可能不起作用。

我已经阅读了一些正则表达式。但不确定我是否正确测试它,因为它没有完全得到我想要的输出。例如

string input = "USD 2.4700/Tgt sh.";

string[] numbers = Regex.Split(input, @"\D+");
foreach (string value in numbers)
{
    if (!string.IsNullOrEmpty(value))
    {
        int i = int.Parse(value);
        Console.WriteLine("Number: {0}", i);
    }
}

但输出是,

2 47

虽然我期待2.47而且我也不想丢失文本。我想要的结果是

  

myText =“USD Tgt sh。”   myNum = 2.47

对于另一个例子

  

myText =“Aqr sh./Tgt sh。”   myNum = 0.27

我的代码

string[] sData = sTerms.Split(' ');

double num;
bool isNum = double.TryParse(sData[0], out num);

if(isNum)
{
    ma.StockTermsNum = num;

    StringBuilder sb = new StringBuilder();
    for (int i = 1; i < sData.Length; i++)
        sb = sb.Append(sData[i] + " ");

    ma.StockTerms = sb.ToString();
}
else
{
    string[] sNSplit = sData[1].Split('/');

    ma.StockTermsNum = Convert.ToDouble(sNSplit[0]);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < sData.Length; i++)
    {
        if (i == 1)                            
            sb = sb.Append(sNSplit[i] + " ");                            
        else
            sb = sb.Append(sData[i] + " ");
    }                            
    ma.StockTerms = sb.ToString();
}

3 个答案:

答案 0 :(得分:2)

我建议按群组(...)进行拆分,以便保留分隔符

  string source = @".2700 Aqr sh./Tgt sh.";
  //string source = "USD 2.4700/Tgt sh.";

  // please, notice "(...)" in the pattern - group
  string[] parts = Regex.Split(source, @"([0-9]*\.?[0-9]+)");

  // combining all texts
  string myText   = string.Concat(parts.Where((v, i) => i % 2 == 0));
  // combining all numbers
  string myNumber = string.Concat(parts.Where((v, i) => i % 2 != 0));

试验:

  string[] tests = new string[] {
     @".2700 Aqr sh./Tgt sh.",
     @"USD 2.4700/Tgt sh.",
  };

  var result = tests
    .Select(test => new {
      text = test,
      parts = Regex.Split(test, @"([0-9]*\.?[0-9]+)"),
    })
    .Select(item => new {
      text = item.text,
      myText = string.Concat(item.parts.Where((v, i) => i % 2 == 0)),
      myNumber = string.Concat(item.parts.Where((v, i) => i % 2 != 0)),
    })
    .Select(item => $"{item.text,-25} : {item.myNumber,-15} : {item.myText}");

  Console.WriteLine(string.Join(Environment.NewLine, result));

结果:

 .2700 Aqr sh./Tgt sh.     :  Aqr sh./Tgt sh.   : .2700
 USD 2.4700/Tgt sh.        : USD /Tgt sh.       : 2.4700

答案 1 :(得分:0)

可以通过类似这样的正则表达式:

string input = "USD 2.4700/Tgt sh.";

var numbers = Regex.Matches(input, @"[\d]+\.?[\d]*");
foreach (Match res in numbers)
{
    if (!string.IsNullOrEmpty(res.Value))
    {
        decimal i = decimal.Parse(res.Value);
        Console.WriteLine("Number: {0}", i);
    }
}

答案 2 :(得分:0)

我建议你使用System.Text.RegularExpressions.RegEx。以下是如何实现它的示例:

static void Main(string[] args)
{
    string a1 = ".2700 Aqr sh./Tgt sh.";
    string a2 = "USD 2.4700/Tgt sh.";
    var firstStringNums = GetNumbersFromString(ref a1);
    Console.Write("My Text: {0}",a1);
    Console.Write("myNums: ");
    foreach(double a in firstStringNums)
    {
        Console.Write(a +"\t");
    }
    var secondStringNums = GetNumbersFromString(ref a2);
    Console.Write("My Text: {0}", a2);
    Console.Write("myNums: ");
    foreach (double a in secondStringNums)
    {
        Console.Write(a + "\t");
    }
}

public static List<double> GetNumbersFromString(ref string input)
{
    List<double> result = new List<double>();
    Regex r = new Regex("[0-9.,]+");
    var numsFromString = r.Matches(input);
    foreach(Match a in numsFromString)
    {
        if(double.TryParse(a.Value,out double val))
        {
            result.Add(val);
            input =input.Replace(a.Value, "");
        }
    }
    return result;
}

这种模式只是一个例子,当然不会涵盖你想象的每一个案例。