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
    That's too much code dude!!.Please post essential part. Commented Sep 20, 2013 at 12:24
  • Ok, will do. I'll post a link to the full code for anyone who needs it. Commented Sep 20, 2013 at 12:25
  • @user2798632 Have you considered using a simple state machine? That might work. Another approach would be to finalize the prior value only after you confirm that the next name isn't a continuation of the prior one. Commented Sep 20, 2013 at 12:27
  • @Eric Stein I've never used state machines and don't know anything about them. I've also thought about the approach you mentioned but I'm still tring to figure out how to do that :/ Commented Sep 20, 2013 at 12:35

2 Answers 2

3

The way you are doing it is a little bit complicated (sorry I didn't even read the hole code).

From the output you are wanting to have, this is how I would do it:

I would use a Map which has as key the name without the the part after the underscore and as value a List of values.

I.e.:

When you read a line starting with Name extract that name from the line and remove the part after the the underscore (including). Save that name in variable whitch remains persistent through the loops.

When you read a line starting with Value extract the value again and look up the corresponding List from the Map using the name you have saved before. If the List does not exist, then create one and put it into the Map. Then add the value into the List.

Here is how it looks like:

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;
}

And for some testing I used the sample text you have posted:

@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());
}

Output

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

Hope this helps!

Sign up to request clarification or add additional context in comments.

9 Comments

@EricStein, I dont thik this looks like home work, and less the answer is worth downvoting, and whoever did, he should at least leave a constructive comment.
Totally agree. I upvoted just to balance out the undeserved downvote.
@Eric Stein this is not homework. My boss has given me the task of doing some coding (of which I know a little Java) and I've run into this problem.
@A4L I think I can change this around. Is there any way to remove the brackets? I would upvote answer but not enough Rep(15).
@user2798632 the brackest come only from the List#toString(), the elements inside the list are all ok, just iterate over the list and get the values! -> for(String valueWithoutBrackets : list) { ... }
|
1

Base idea - to create output map like "name -> (list of values)". Thereafter - print it. But I not sure, is java suitable instrument for solve this task. See my program on PERL, which does this job:

#!/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";
}

Output for your sample:

$ ./nv.pl nv.txt
AdrIctPcbTesTime = FF
AdrIctPcbTestDate = FF FF
partHeader = 10 9 95 38
AdrIctPcbTestTime = FF

3 Comments

Thanks for the answer. The output is almost right but I don't know PERL and this is just part of a bigger program already written in Java.
I edited program, and this version removes "0x" at begin of each value, if exist. Also, it links pairs "Name=Value" by index, not by line number..
Haha thanks again. It'll come in handy for those who know PERL anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.