以下是非常大文件的一小部分摘录。
我正在寻找一种方法来将每个名称和值(在 Name(x)和 Value(x)行上)放入数组元素中或列表类型,两者之间带“=”。
即使每个元素看起来像“'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
到目前为止,我可以获得名称和价值观。我的问题是,当一个部分有超过1个字节(在名称中用“_”表示)时,我需要将所有字节值放在同一个元素中只有一个名称。
我无法找到合适的算法来使其正常工作。
即 partHeaderArtLK_A01 ,最多 partHeaderArtLK_A04 ,而不是
partHeaderArtLK_A01 = 10
partHeaderArtLK_A02 = 09
partHeaderArtLK_A03 = 95
partHeaderArtLK_A04 = 38
该元素应该看起来像
partHeaderArtLK = 10 09 95 38 。
(注意:我插入了虚线分隔符以使事情更清晰。它们不会(也不能)存在于实际文件中。)
到目前为止,这是我的尝试:
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
以下是完整代码的链接:http://justpaste.it/d3u0
所有算法或代码都受到赞赏。
提前致谢!
答案 0 :(得分:3)
你这样做的方式有点复杂(对不起,我甚至没有看过漏洞代码)。
从你想要的输出中,我就是这样做的:
我会使用Map
作为键的名称,而不是下划线后的部分,值为List
的值。
即:
当您读取以Name
开头的行时,从行中提取该名称并删除下划线后面的部分(包括)。将该名称保存在变量whitch中,通过循环保持持久。
当您阅读以Value
开头的行时,再次提取该值并使用您之前保存的名称从List
中查找相应的Map
。如果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]
希望这有帮助!
答案 1 :(得分:1)
基本理念 - 创建输出地图,例如“name - &gt;(值列表)”。此后 - 打印出来。 但我不确定,是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