2011-12-13 100 views
0

我有一个包含下列值的数组:字符串分割到

str[0]= "MeterNr 29202" 
str[1]="- 20111101: position 61699 (Previous calculation) " 
str[2]="- 20111201: position 68590 (Calculation) consumption 6891 kWh" 
str[3]="- 20111101: position 75019 (Previous calculation) " 
str[4]="MeterNr 50273" 
str[5]="- 20111101: position 18103 (Previous reading) " 
str[6]="- 20111201: position 19072 (Calculation) consumption 969 kWh " 

我想在逻辑顺序行分割,这样我可以将它们存储在下面的阅读课。我在分割值时遇到问题。括号()中的所有内容都是ItemDescription。

我会感谢您的快速回答。

public class Reading 
{ 
    public string MeterNr { get; set; } 

    public string ItemDescription { get; set; } 

    public string Date { get; set; } 

    public string Position { get; set; } 

    public string Consumption { get; set; } 
} 
+0

你能否更具体?输出应该如何?换句话说,应该返回MeterNr,ItemDescription等。 – Perlnika

+0

有几种选择。一个是检查(IndexOf)的开始(和结束),并采取内部。或者你可以用正则表达式来做到这一点。 – lnu

+0

尝试使用英语(或您选择的语言)来描述您想要的每一行内容,那应该给您提示您应该做什么。进一步的提示:它似乎并不需要*正则表达式,一个简单的IndexOf/substring已经可以提供帮助。 –

回答

2

我只是使用一个for循环和字符串索引等,但后来我有点简单!不知道你的数据(即,如果事情可能会丢失),但是这会在您发布的数据工作...

var readings = new List<Reading>(); 
int meterNrLength = "MeterNr".Length; 
int positionLength = "position".Length; 
int consumptionLength = "consumption".Length; 
string meterNr = null; 

foreach(var s in str) 
{ 
    int meterNrIndex = s.IndexOf("MeterNr", 
           StringComparison.OrdinalIgnoreCase); 

    if (meterNrIndex != -1) 
    { 
     meterNr = s.Substring(meterNrIndex + meterNrLength).Trim(); 
     continue; 
    } 

    var reading = new Reading {MeterNr = meterNr}; 

    string rest = s.Substring(0, s.IndexOf(':')); 
    reading.Date = rest.Substring(1).Trim(); 

    rest = s.Substring(s.IndexOf("position") + positionLength); 

    int bracketIndex = rest.IndexOf('('); 

    reading.Position = rest.Substring(0, bracketIndex).Trim(); 

    rest = rest.Substring(bracketIndex + 1); 

    reading.ItemDescription = rest.Substring(0, rest.IndexOf(")")); 

    int consumptionIndex = rest.IndexOf("consumption", 
             StringComparison.OrdinalIgnoreCase); 

    if (consumptionIndex != -1) 
    { 
     reading.Consumption = rest.Substring(consumptionIndex + consumptionLength).Trim(); 
    } 

    readings.Add(reading); 
} 
2

您应该逐一解析这些值。 如果您有一个以“MeterNr”开头的字符串,则应将其保存为currentMeterNumber并进一步解析这些值。 否则,你可以用正则表达式解析值:

var dateRegex = new Regex(@"(?<=-\s)(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})"); 
var positionRegex = new Regex(@"(?<=position\s+)(\d+)"); 
var descriptionRegex = new Regex(@"(?<=\()(?<description>[^)]+)(?=\))"); 
var consuptionRegex = new Regex(@"(?<=consumption\s+)(?<consumption>(?<consumtionValue>\d+)\s(?<consumptionUom>\w+))"); 

我希望,你将能够创建最终的算法,以及了解每个这些表达式的工作。最后一点可能是将它们全部组合成单个正则表达式。你应该自己做,以提高你的技能。

P.S .:网上有很多教程。

+0

输入是基于数字模式和括号中的描述。不需要4种不同的正则表达式模式。 – 2011-12-13 11:54:39

+0

我认为,输入的形式是:'dataPrefix dataValue',如:“ - ”是日期前缀,“20111213”是日期本身。 “位置”是日期前缀,64699是位置本身。并且所有这些“名称值”对都可以按照任意顺序进行操作 –

+0

这是一个有效的假设,但在这种情况下,似乎输入是特定/格式化的,并且它的来源不是正在键入的人。 – 2011-12-13 12:22:26

0
public static List<Reading> Parser(this string[] str) 
{ 
    List<Reading> result = new List<Reading>(); 
    string meterNr = ""; 
    Reading reading; 
    foreach (string s in str) 
    { 
     MatchCollection mc = Regex.Matches(s, "\\d+|\\((.*?)\\)"); 
     if (mc.Count == 1) 
     { 
      meterNr = mc[0].Value; 
      continue; 
     } 
     reading = new Reading() 
     { 
      MeterNr = meterNr, 
      Date = mc[0].Value, 
      Position = mc[1].Value, 
      ItemDescription = mc[2].Value.TrimStart('(').TrimEnd(')') 
     }; 
     if (mc.Count == 4) 
      reading.Consumption = mc[3].Value; 
     result.Add(reading);    
    } 
    return result; 
}