是否可以在 dna 字符串上使用正则表达式进行查找/替换,这样它一次只考虑每 3 个字符(dna 的密码子)。
例如,我希望正则表达式可以看到:
dna="AAACCCTTTGGG"
如下:
AAA CCC TTT GGG
如果我现在使用正则表达式并且表达式是
Regex.Replace(dna,"ACC","AAA") 它会找到匹配项,但在这种情况下一次查看 3 个字符将没有匹配项。
这可能吗?
可以使用正则表达式来做到这一点。假设输入有效(仅包含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
),后面是替换密码子。
为什么使用正则表达式?试试这个,这可能更有效地启动:
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();
}
笔记
正如评论中所解释的,以下不是一个好的解决方案!我把它留在里面,这样其他人就不会犯同样的错误
m.start()
您通常可以通过和找出匹配的开始和结束位置m.end()
。如果m.start() % 3 == 0
您找到了相关匹配项。