从C#中的字符串行获取特定字段或字符

时间:2018-09-03 06:53:51

标签: c# regex pattern-matching

我只有一个文件,并逐行读取文件,并从字符串行中提取特定对象。

例如字符串行有两种格式。

VA001748714600006640126132202STRONG 4P 4X44G000099

VA 00174 871460000664 012 6132202 STRONG 4P 4X44G 000099

现在我需要提取字符串并将其存储到我的表中,并在下面的字段(期望结果)中生成两行以下的数据。

 Code  Location    SerialNo     Quantity  ItemNo      Description      Price
  VA    00174     871460000664     12     6132202    STRONG 4P 4X44G0  000099

我尝试过的。我已经创建了一种返回object[]从字符串中提取的方法

public static object[] ProcessLine(string line)
{
        var obj = new object[7];
        var str = line.Replace("\0", "").Replace(" ", "");
        string code = str.Substring(0, 2)?.Trim();
        string location = str.Substring(2, 5)?.Trim();
        string serialNo = str.Substring(7, 12)?.Trim();
        string quantity = str.Substring(19, 3)?.Trim();
        int qty = 0;
        if (!string.IsNullOrEmpty(quantity))
        {
            qty = Convert.ToInt32(quantity);
        }
        string itemNo = str.Substring(22, 7)?.Trim();
        Regex MyRegex = new Regex("[^a-z ]", RegexOptions.IgnoreCase);
        string description = MyRegex.Replace(line.Substring(2), @"")?.Trim();
        string price = str.Substring(str.Length - 6)?.Trim();
        obj.SetValue(code, 0);
        obj.SetValue(location, 1);
        obj.SetValue(serialNo, 2);
        obj.SetValue(qty, 3);
        obj.SetValue(itemNo, 4);
        obj.SetValue(description, 5);
        obj.SetValue(price, 6);
        return obj;
}

我找到了子字符串并存储到对象中,也找不到描述,因为该字段不是固定字母。

(Code,Location,SerialNo,Quantity,ItemNo and Price)是固定的字符数,(Description)字段是任何字符或更改。

如何使用regex查找此字段的值和说明,我尝试查找说明,但提取时没有数字。

2 个答案:

答案 0 :(得分:2)

如果您确实要使用正则表达式,请参见Wiktor's answer

但是,您不需要正则表达式来解决此问题。

由于除说明以外的所有字段都有已知长度,因此您可以计算说明字段的长度。根据您的规格,说明从第29位开始,然后是价格字段的6个位置。因此,这应该为您提供描述:

string description = str.Substring(29, str.Length-29-6);

答案 1 :(得分:1)

您可以声明正则表达式,例如

private static readonly Regex rx = new Regex(@"^(\w{2})\s*(\w{5})\s*(\w{12})\s*(\d{3})\s*(\d{7})\s*(.*?)\s*(\d{6})$", RegexOptions.Compiled);

请参见regex demo

重点是使用匹配整个字符串的正则表达式(^匹配字符串的开头,$匹配字符串的结尾),使用\w(任何字母/ digit / _字符)或\d(任何数字字符),{m}量词以匹配与\w\d匹配的一定数量的字符,将Description字段与.*?进行匹配,这是一种惰性点模式,它尽可能少地匹配除换行符以外的任何0+字符,并允许带有\s*的字段之间的任何0+空格字符。

然后,您可以使用它

public static object[] ProcessLine(string line)
{
    object[] obj = null;
    var m = rx.Match(line);
    if (m.Success)
    {
        obj = new object[] {
            m.Groups[1].Value,
            m.Groups[2].Value,
            m.Groups[3].Value,
            int.Parse(m.Groups[4].Value).ToString(), // remove leading zeros
            m.Groups[5].Value,
            m.Groups[6].Value,
            m.Groups[7].Value
        };
    }
    return obj;
}

请参见C# demo的OP中两个字符串的演示输出:

VA, 00174, 871460000664, 12, 6132202, KING PEPERM E STRONG 4P 4X44G, 000099
VA, 00174, 871460000664, 12, 6132202, KING PEPERM E STRONG 4P 4X44G, 000099