5

Below is a small extract of a very large file.

I'm looking for a way to get each name and value (on the Name(x) and Value(x) lines) into an element of a Array or List type with an "=" between the two.

i.e to get each element to look like " 'name' = 'value' ".

[Device|EEP_FEATUREKOI_HFS_Max|Kostia]
--------------------------------
Name(1) = partHeader_A01
Value(1) = 0x10
Desc(1) = (Address 0x000) Article No. / P.C.B No Byte 1
Name(2) = partHeader_A02
Value(2) = 0x9
Desc(2) = (Address 0x001) Article No. / P.C.B No Byte 2
Name(3) = partHeader_A03
Value(3) = 0x95
Desc(3) = (Address 0x002) Article No. / P.C.B No Byte 3
Name(4) = partHeader_A04
Value(4) = 0x38
Desc(4) = (Address 0x003) Article No. / P.C.B No Byte 4
----------------------------------
Name(12) = AdrIctPcbTestDate_Day
Value(12) = 0xFF
Desc(12) = (Address 0x00B) Test Date : Day
---------------------------------
Name(13) = AdrIctPcbTestDate_Month
Value(13) = 0xFF
Desc(13) = (Address 0x00C) Test Date : Month
---------------------------------
Name(14) = AdrIctPcbTestTime_Hour
Value(14) = 0xFF
Desc(14) = (Address 0x00D) Test Time : Hour
---------------------------------
Name(15) = AdrIctPcbTesTime_Minute
Value(15) = 0xFF
Desc(15) = (Address 0x00E) Test Time : Minute

So far I can get the names and values. My problem is, when a section has more than 1 byte(denoted with a "_" in the name) I need to place all the byte values in the same element with only one name.

I can't figure out the proper algorithm to get this to work right.

i.e, for partHeaderArtLK_A01 up to partHeaderArtLK_A04, instead of having

partHeaderArtLK_A01 = 10

partHeaderArtLK_A02 = 09

partHeaderArtLK_A03 = 95

partHeaderArtLK_A04 = 38

The element would should to look like

partHeaderArtLK = 10 09 95 38.

(Note: I inserted the dashed line seperators to make things clearer. They don't (and cannot) exist in the actual file.)

Here's my attempt so far:

if (line.contains("Name")&& line.contains("_")) {
   String basicName = line;
   cutName = basicName.split("=")[1].trim();//get substring after '='
   cutName = cutName.substring(0,cutName.lastIndexOf("_"));//removes '_'?

   importantName.add(i, (cutName + " = "));//add to element i
   System.out.println("Line reads: " + basicName);
   System.out.println("Part: " + cutName);

   do{                   
    if (line.contains("Value")) {
      Hex = line.split("=")[1].trim();//get substring after '='
      importantNumber.add(i, Hex);//get substring after '='
      System.out.println("Value: " + Hex);                        
    }//end if                  
  }while(!"Value".contains(line = reader.readLine()));
   while (!placeToFinish[i].equals(line = reader.readLine()));

 }else    
   if(line.contains("Name")) {
     String basicName = line;
     cutName = basicName.split("=")[1].trim();//get substring after '='

     importantName.add(i, (cutName + " = "));//get substring after '='
     System.out.println("Line reads: " + basicName);
     System.out.println("Part: " + cutName);
     System.out.println("Number: " + importantNumber.indexOf(i) + "\n"); 

    do{  
      if (line.contains("Value")) {
       Hex = line.split("=")[1].trim();//get substring after '='
       importantNumber.add(i, Hex);//get substring after '='
     }//end if                    
   }while (!"Value".contains(line = reader.readLine()));
    while (!placeToFinish[i].equals(line = reader.readLine()));
 }//end if

Here's the link to the full code: http://justpaste.it/d3u0
All algorithms or code is appreciated.

Thanks in advance!

4

2 回答 2

3

你这样做的方式有点复杂(对不起,我什至没有阅读漏洞代码)。

根据您想要的输出,我将这样做:

我会使用 aMap作为键名,没有下划线后的部分,作为值的 aList值。

IE:

当您阅读以Name从该行中提取该名称开头的行并删除下划线(包括)之后的部分时。将该名称保存在变量 whitch 中,在循环中保持不变。

当您再次读取以提取值开头的行并使用您之前保存的名称Value查找对应的值时ListMap如果List不存在,则创建一个并将其放入Map. 然后将值添加到List.

这是它的样子:

private Map<String, List<String>> readValues(BufferedReader reader) throws IOException {
    Map<String, List<String>> nameToValuesMap  = new HashMap<String, List<String>>();
    String line = null;
    String actName = null; 
    while((line = reader.readLine()) != null) {
        if(line.startsWith("Name")) {
            String[] split = line.split("\\s*=\\s*", 2);
            String name = split[1];
            int i = name.indexOf('_');
            if(i != -1) {
                name = name.substring(0, i);
            }
            actName = name;
        } else if(line.startsWith("Value")) {
            String[] split = line.split("\\s*=\\s*", 2);
            String value = split[1].replace("0x", "");
            if(actName != null) {
                List<String> values = nameToValuesMap.get(actName);
                if(values == null) {
                    values = new ArrayList<String>();
                    nameToValuesMap.put(actName, values);
                }
                values.add(value);
            }
        }
    }

    return nameToValuesMap;
}

对于一些测试,我使用了您发布的示例文本:

@Test
public void readpartValues() throws IOException {
    String fielData = "[Device|EEP_FEATUREKOI_HFS_Max|Kostia]\r\n" + 
            "--------------------------------\r\n" + 
            "Name(1) = partHeader_A01\r\n" + 
            "Value(1) = 0x10\r\n" + 
            "Desc(1) = (Address 0x000) Article No. / P.C.B No Byte 1\r\n" + 
            "Name(2) = partHeader_A02\r\n" + 
            "Value(2) = 0x9\r\n" + 
            "Desc(2) = (Address 0x001) Article No. / P.C.B No Byte 2\r\n" + 
            "Name(3) = partHeader_A03\r\n" + 
            "Value(3) = 0x95\r\n" + 
            "Desc(3) = (Address 0x002) Article No. / P.C.B No Byte 3\r\n" + 
            "Name(4) = partHeader_A04\r\n" + 
            "Value(4) = 0x38\r\n" + 
            "Desc(4) = (Address 0x003) Article No. / P.C.B No Byte 4\r\n" + 
            "----------------------------------\r\n" + 
            "Name(12) = AdrIctPcbTestDate_Day\r\n" + 
            "Value(12) = 0xFF\r\n" + 
            "Desc(12) = (Address 0x00B) Test Date : Day\r\n" + 
            "---------------------------------\r\n" + 
            "Name(13) = AdrIctPcbTestDate_Month\r\n" + 
            "Value(13) = 0xFF\r\n" + 
            "Desc(13) = (Address 0x00C) Test Date : Month\r\n" + 
            "---------------------------------\r\n" + 
            "Name(14) = AdrIctPcbTestTime_Hour\r\n" + 
            "Value(14) = 0xFF\r\n" + 
            "Desc(14) = (Address 0x00D) Test Time : Hour\r\n" + 
            "---------------------------------\r\n" + 
            "Name(15) = AdrIctPcbTesTime_Minute\r\n" + 
            "Value(15) = 0xFF\r\n" + 
            "Desc(15) = (Address 0x00E) Test Time : Minute";


    BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(fielData.getBytes())));

    Map<String, List<String>> nameToValuesMap  = readValues(reader);
    reader.close();

    List<String> partHeaderValues = nameToValuesMap.get("partHeader");
    System.out.println("partHeader = " + partHeaderValues.toString());

    List<String> adrIctPcbTestTimeValues = nameToValuesMap.get("AdrIctPcbTestTime");
    System.out.println("AdrIctPcbTestTime = " + adrIctPcbTestTimeValues.toString());
}

输出

partHeader = [10, 9, 95, 38]
AdrIctPcbTestTime = [FF]

希望这可以帮助!

于 2013-09-20T12:59:30.110 回答
1

基本思想 - 创建像“名称 - >(值列表)”这样的输出映射。此后 - 打印它。但我不确定,Java 是否适合解决此任务。请参阅我在 PERL 上的程序,它可以完成这项工作:

#!/usr/local/bin/perl -w

my %nv;
while(<>) {
  my ($nm, $ndx, $val) = m/^(\w+)?\((\d+)\)\s*=\s*(\w+)/;
  next unless $val;
  $nv{$ndx}{$nm} = $val;
}

my %out;
foreach my $k(sort keys %nv) {
  my $name = $nv{$k}{"Name"};
  $name =~ s/_.+//;
  push(@{$out{$name}}, map {s/^0x//; $_ } $nv{$k}{"Value"});
}

while(my ($nm, $vlist) = each %out) {
  print "$nm = " . join(" ", @{$vlist}) . "\n";
}

样品的输出:

$ ./nv.pl nv.txt
AdrIctPcbTesTime = FF
AdrIctPcbTestDate = FF FF
partHeader = 10 9 95 38
AdrIctPcbTestTime = FF
于 2013-09-20T13:11:09.250 回答