我正在使用 Java 处理一个非常大的蛋白质 .txt 文件数据库。这些蛋白质具有通用结构,但不够统一,无法硬编码“从 startIndex 到 endIndex,反转并替换”。唯一真正的统一性是它们由 >
分隔,例如:
...WERINWETI>gi|230498 [牛白蛋白]ADFIJWOENAONFOAIDNFKLSADNFATHISDATFDAIFJ>sp|234235(人)AGP1 QWIQWONOQWNROIWQRNOQWIRNSWELLE>gi|...
等等。
正如你所看到的,虽然实际的蛋白质序列(所有大写的长链)是统一的,因为它们都是大写的链,但除此之外,前面的描述几乎可以是任何东西(有很多时候描述和序列之间没有空格)。我的程序需要做的是将原始文本复制到一个新文件中,然后在每个 >
之后添加一个 r-
(例如 ... EERFDS>r-gi|23423...
) 以及仅反转资本链。该过程完成后,我需要将其附加到原始文本的末尾。
我已经完成了r-
功能,实际上我也完成了反转和追加,但是效率不够。接受这种处理的数据库非常庞大,而我的程序花费的时间太长。事实上我不知道需要多长时间,因为我从来没有让它完成。我等了1个小时就结束了。这是我使用正则表达式(内置 Pattern 类)(计算密集型部分)的反转算法:
Pattern regexSplit = Pattern.compile(">");
String[] splits = regexSplit.split(rDash.toString());
StringBuilder rDashEdited = new StringBuilder();
Pattern regexProtein = Pattern.compile("[A-Z]{5,}");
for (int splitIndex = 1; splitIndex < splits.length; splitIndex++) {
Matcher rDashMatcher = regexProtein.matcher(splits[splitIndex]);
rDashMatcher.find();
StringBuffer reverser = new StringBuffer(rDashMatcher.group());
rDashEdited.append(rDashMatcher.replaceAll(reverser.reverse().toString()) + ">");
}
System.out.println(">" + rDashEdited);
所以,基本上我拆分了 rDash
(这是一个 StringBuilder,其中包含所有带有 >r-
的原始蛋白质,但尚未经过反转)到每个单独的蛋白质中并将它们添加到字符串数组中。然后,我遍历数组中的每个字符串,查找长度超过 5 个字母的大写字母链,将匹配项添加到 StringBuffer 中,反转它,并将正向版本替换为反向版本。请注意,此算法适用于较小的文本文件。
是否有更强大的正则表达式可以消除拆分/遍历数组的需要?当我尝试时,replaceAll()
调用将所有下游蛋白质替换为集合中第一个蛋白质的反向蛋白质。为了好玩,我用 System.out.println(rDashMatcher.groupCount()) 进行了检查,它为该组中的每个蛋白质打印了一个 0
。谁能帮我提供更高效/更强大的正则表达式?这对我来说是一个相当新的概念,但它让我想起了 MATLAB 中的矢量化(仅使用字母)。
最佳答案
我为此扔了 10,000,000 条记录(大约 379MB 文本文件),花了 1 分 06 分钟。(4core athlon,几年前)
大 if 树处理末端,因为分隔符位于元素的中间,因此您只能得到一半。
public void readProteins(BufferedReader br, BufferedWriter bw) throws IOException
{
Pattern regexSplit = Pattern.compile(">");
Pattern proteinPattern = Pattern.compile("(.*?)([A-Z]{5,})");
Matcher m;
Scanner s = new Scanner(br);
s.useDelimiter(regexSplit);
while (s.hasNext())
{
StringBuffer sb = new StringBuffer();
String protein = s.next();
m = proteinPattern.matcher(protein);
if (m.find())
sb.append(m.group(2)).reverse().append(">r-").insert(0, m.group(1));
else
sb.append(protein);
);
}
bw.flush();
bw.close();
}
关于java - 查找,然后高效地用java中的相反内容替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11268946/