1

我对正则表达式有点麻烦。我有以下一个:(A|C|G|T){3}它给出了 A、B、C、D 三个字母的每个排列,但现在我想排除三个特定模式"TAG""TAA""TGA". 尝试使用[^],但没有产生预期的结果。使用环视(向前看和向后看)也是如此。

我想要实现的是找到所有以“ATG”开头、以“TAG”、“TAA”或“TGA”结尾的子字符串,中间应该有三元组A、C、G或T .

谢谢您的帮助!

这是我到目前为止所做的:

(ATG)((((A|C|G|T)){3})[^TAG][^TAA][^TGA])*(TAG|TAA|TGA)

(ATG)((?!TAG)(?!TAA)(?!TGA)(((A|C|G|T)){3})*)(TAG|TAA|TGA)
4

2 回答 2

5

如果我理解正确:

1) 从 ATG 开始

2) 一些三元组,除了 'TAG'、'TAA' 和 'TGA'

3) 三元组“TAG”、“TAA”或“TGA”之一

这应该有效:

/
   (ATG)                       # Step 1
   ((?!TAG|TAA|TGA)[ACGT]{3})+ # Step 2
   (TAG|TAA|TGA)               # Step 3
/x

与您的第二个想法的不同之处在于,它在量词内移动负前瞻以获得“多个三元组”步骤,确保三个三元组都不是例外之一

此解决方案不假定步骤 2 和步骤 3 中的元素之间有任何共性。更简单但在您的情况下等效的公式是:

1) 匹配“ATG”

2)匹配多个三元组

3) ...直到你匹配'TAG'、'TAA'、'TGA'。

为此,您只需使第 2 步中的量词不贪心,因为这将测试第 3 步是否匹配,然后再尝试第 2 步是否再次匹配。

那么解决方案将如下所示:

/ (ATG) ([ACGT]{3})*? (TAG|TAA|TGA) /x

另一种解释可能是:

1) 从 ATG 开始

2) 多个三元组

3) 三元组“TAG”、“TAA”、“TGA”之一

4) 步骤 2 中找到的子串不得包含子串 'TAG'、'TAA'、'TGA'。

在这种情况下,我将使用两个正则表达式来解决它。在执行步骤 1-3 和步骤 4 中的测试时:

 $sequence =~ /(ATG)([ACGT]{3})(TAG|TAA|TGA)/ and $2 !~ /TAG|TAA|TGA/;
于 2012-11-29T11:21:36.383 回答
0

在您的情况下,您不必排除中间的任何内容 - 假设您希望最长的序列匹配。这就是 Perl 所做的*并且+已经做到了:它们是贪婪的并且匹配尽可能长的序列。

因此,在一个简化的示例中,如果您的输入是ABAACAAC并且您想要匹配以B结尾的C所有内容AB或者C在中间匹配所有内容,那么m/A[ABC]*C/将已经匹配BAACAAC,而不仅仅是BAAC.

通常,您不能使用正则表达式来很好地排除中间的特定事物(尽管有诸如零宽度负前瞻/后瞻断言之类的东西)。

编辑:如果你想在第一次出现“结束模式”时停止匹配,那么只需*通过使用?. 我的非贪婪示例:m/A[ABC]*?C/,尽管对于这种情况,我也可以从 char 类中省略C(因为在这个简化的示例中它只是一个字母)。

于 2012-11-29T11:17:35.607 回答