java - 查找,然后高效地用java中的相反内容替换

标签 java regex performance

我正在使用 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/

相关文章:

java - 适用于 Android 的 Xerces

java - 从数据库获取字符串时未找到新行字符

c# - 使用 PowerShell Split 和正则表达式在正则表达式匹配后返回所有内容

performance - 假设需要 f(n) 微秒,一秒内可解决的最大难题是什么?

java - 如何在 Java 中复制对象?

php - 正则表达式: does not contain

php - MYSQL子查询和正则表达式

java - 通过 SOAP 流式传输?

performance - SSE2 : How To Load Data From Non-Contiguous Memory Locations?

Eclipse 中的 Java 方法观察点