2

是否可以在 dna 字符串上使用正则表达式进行查找/替换,这样它一次只考虑每 3 个字符(dna 的密码子)。

例如,我希望正则表达式可以看到:
dna="AAACCCTTTGGG"
如下:
AAA CCC TTT GGG

如果我现在使用正则表达式并且表达式是
Regex.Replace(dna,"ACC","AAA") 它会找到匹配项,但在这种情况下一次查看 3 个字符将没有匹配项。

这可能吗?

4

3 回答 3

1

解决方案

可以使用正则表达式来做到这一点。假设输入有效(仅包含A, T, G, C):

Regex.Replace(input, @"\G((?:.{3})*?)" + codon, "$1" + replacement);

演示

如果不能保证输入有效,您可以使用正则表达式^[ATCG]*$(允许非 3 的倍数)或^([ATCG]{3})*$(序列必须是 3 的倍数)进行检查。无论如何,对无效输入进行操作是没有意义的。

解释

上述结构适用于任何密码子。为了解释起见,设密码子为AAA。正则表达式将是\G((?:.{3})*?)AAA.

整个正则表达式实际上匹配以要替换的密码子结尾的最短子字符串。

\G            # Must be at beginning of the string, or where last match left off
((?:.{3})*?)  # Match any number of codon, lazily. The text is also captured.
AAA           # The codon we want to replace

我们确保匹配只从索引为 3 的倍数的位置开始:

  • \G它断言匹配从前一个匹配停止的地方(或字符串的开头)开始
  • 而且该模式((?:.{3})*?)AAA只能匹配长度为 3 的倍数的序列。

由于惰性量词,我们可以确定在每次匹配中,要替换的密码子之前的部分(由((?:.{3})*?)部分匹配)不包含密码子。

在替换中,我们放回密码子之前的部分(在捕获组 1 中捕获,可以用 引用$1),后面是替换密码子。

于 2013-05-11T18:09:48.557 回答
1

为什么使用正则表达式?试试这个,这可能更有效地启动:

public string DnaReplaceCodon(string input, string match, string replace) {
  if (match.Length != 3  || replace.Length != 3) 
      throw new ArgumentOutOfRangeException();

  var output = new StringBuilder(input.Length);
  int i = 0;
  while (i + 2 < input.Length) {
    if (input[i] == match[0] && input[i+1] == match[1] && input[i+2] == match[2]) {
      output.Append(replace);
    } else {
      output.Append(input[i]);
      output.Append(input[i]+1);
      output.Append(input[i]+2);
    }

    i += 3;
  }

  // pick up trailing letters.
  while (i < input.Length)   output.Append(input[i]);

  return output.ToString();
}
于 2013-05-11T17:50:35.243 回答
0

笔记

正如评论中所解释的,以下不是一个好的解决方案!我把它留在里面,这样其他人就不会犯同样的错误

m.start()您通常可以通过和找出匹配的开始和结束位置m.end()。如果m.start() % 3 == 0您找到了相关匹配项。

于 2013-05-11T17:43:31.393 回答