解析文本文件一行行,跳过某些行
我有一个看起来像这样(但更大)的文件:解析文本文件一行行,跳过某些行
>some text
ABC
DEF
GHI
>some more text
JKL
MNO
PQR
我已经玩了Java中有一段时间,并已能够用线条构建数组等。具有'>'的线条通常是一条线,但有时可能是2条,3条或更多条线。不以'>'开始的行的字符长度相同,但可能有10,20或30或更多这些行。我在点现在在哪里,我想创建一个字符串数组,数组中的每个字符串包含不以“>”,像这样开头的行的字符串:
array element 1 = ABCDEFGHI
array element 2 = JKLMONPQR
我觉得像我很近,但需要一个小屁股踢我才能去。我确信这对专业人士来说很容易,但我对Java仍然很陌生。
具体问题与我在此板上制作的其他帖子有关。这是一个FASTA文件:
>3BHS_BOVIN (P14893) 3 beta-hydroxysteroid
AGWSCLVTGGGGFLGQRIICLLVEEKDLQEIRVLDKVFRPEVREEFSKLQSKIKLTLLEG
DILDEQCLKGACQGTSVVIHTASVIDVRNAVPRETIMNVNVKGTQLLLEACVQASVPVFI
>41_BOVIN (Q9N179) Protein 4.1
MHCKVSLLDDTVYECVVEKHAKGQDLLKRVCEHLNLLEEDYFGLAIWDNATSKTWLDSAK
EIKKQVRGVPWNFTFNVKFYPPDPAQLTEDITRYYLCLQLRQDIVSGRLPCSFATLALLG
SYTIQSELGDYDPELHGADYVSDFKLAPNQTKELEEKVMELHKSYRSMTPAQADLEFLEN
>5NTD_BOVIN (Q05927) 5'-nucleotidase
MNPGAARTPALRILPLGALLWPAARPWELTILHTNDVHSRLEQTSEDSSKCVNASRCVGG
VARLATKVHQIRRAEPHVLLLDAGDQYQGTIWFTVYKGTEVAHFMNALGYESMALGNHEF
DNGVEGLIDPLLKEVNFPILSANIKAKGPLASKISGLYSPYKILTVGDEVVGIVGYTSKE
TPFLSNPGTNLVFEDEITALQPEVDKLKTLNVNKIIALGHSGFEVDKLIAQKVKGVDVVV
我最终需要在他们自己的数组元素中的序列,以便我可以稍后操作它们。
假设你可以遍历行:
List<String> array = new ArrayList<String>();
StringBuilder buf = new StringBuilder();
for (String line : lines) {
if (line.startsWith(">")) {
if (buf.length() > 0) {
array.add(buf.toString());
buf.setLength(0);
}
} else {
buf.append(line);
}
}
if (buf.length() > 0) { // Add the final text element(s).
array.add(buf.toString());
}
这是一个很好的解决方案。看起来很紧密和高效,除了一件事。对于测试,由于我使用的是具有三个条目的文件,因此如果我打印数组,我只能得到前两个条目,如果我打印buf,则会得到第三个条目。这是一个很好的开始,现在我正在与它一起工作,看看我是否能够一直工作。也许我错过了什么? – nicorellius 2011-06-15 00:54:10
@nicorellius:哎呀,对,我忘了在循环结尾冲洗缓冲区;看我更新的解决方案。 – maerics 2011-06-15 02:14:38
不错!我认为这有点不合适。尽管如此,你做到了完美; - )再次感谢这个伟大的回应。 – nicorellius 2011-06-15 05:17:47
试试这个。我没有打扰适当的变量名称。它也适用于假设第一行有一个>。它可能没有优化,但应该让你知道这是如何可能的。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
public class Parse {
public static void main(String[] args) throws IOException {
String lala = ">some text\r\n" +
"ABC\r\n" +
"DEF\r\n" +
"GHI\r\n" +
">some more text\r\n" +
"JKL\r\n" +
"MNO\r\n" +
"PQR";
ArrayList<String> lines = new ArrayList<String>();
BufferedReader in = new BufferedReader(new StringReader(lala));
String line;
while((line = in.readLine()) != null) {
lines.add(line);
}
ArrayList<String> parsed = new ArrayList<String>();
for(String s : lines) {
if(s.contains(">")) {
parsed.add("");
} else {
String current = parsed.get(parsed.size() - 1);
parsed.set(parsed.size() - 1, current + s);
}
}
for(String s : parsed) {
System.out.println(s);
}
}
}
上面会输出:
ABCDEFGHI
JKLMNOPQR
你能做到这一点的另一个有趣的方法是在“in.readLine()”循环中,您可以检查>,如果它存在添加<在将该字符串推到'行'之前的字符串末尾。然后你可以使用正则表达式来抓取其他线。
为什么要先将行添加到数组中,然后再次遍历数组以删除不必要的条目而不是添加有用的行?太复杂了imo – Voo 2011-06-14 23:31:13
你可以这样做。这有点棘手,因为你可能不得不倒退,因为你会从列表中删除条目。我想这是偏好。我不同意我的方法比你所建议的方法复杂得多。 – 2011-06-14 23:39:04
跳过>
开头的行很简单;
while((line=istream.readLine())!=null){
if(line.charAt(0)=='>')continue;
//do normal concat to buffers
}
,如果你想去就开始>
线下一个缓冲区是有点多地参与
while((line=istream.readLine())!=null){
if(line.charAt(0)=='>'){
//create new buffer and append the current one to the list (check first if current one is not empty)
continue;
}
//do normal concat to buffer
}
像这样的事情?
Array<String> lines
//Open the file for reading
try {
BufferedReader br = new BufferedReader(new FileReader(<FileNameGoesHere>));
while ((thisLine = br.readLine()) != null) { // while loop begins here
if(thisLine.charAt(0) != '>') {
lines.add(thisLine);
}
} // end while
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
什么是* *的具体问题?你知道如何连接字符串吗?你知道如何识别一个字符串是否以'>开头'''? – 2011-06-14 23:11:55
我有一个文件行的数组,我可以确定哪些以'>'开头,是的...我也可以连接行,但只选择那些并将它们作为数组中的元素是我的位置遇到麻烦。 – nicorellius 2011-06-14 23:16:24