4

我正在寻找一个正则表达式,它将标识一个序列,其中文本中的整数指定表达式末尾的尾随字母的数量。此特定示例适用于识别堆积格式的遗传数据中的插入和删除。

例如:

如果我正在搜索的文本是:

AtT+3ACGTTT-1AaTTa

我需要匹配插入和删除,在这种情况下是+3ACGand -1A。整数 (n) 部分可以是任何大于 1 的整数,我必须捕获 n 个尾随字符。

我可以将单个插入或删除与 匹配[+-]?[0-9]+[ACGTNacgtn],但我不知道如何获取整数指定的尾随 ACGTN 的确切数量。

如果这里有一个明显的答案,我很抱歉,我已经搜索了几个小时。谢谢!

(更新)

我通常使用 Python 工作。我已经能够在 python 中使用 re 模块找到的一种解决方法是调用每个 in/del 的整数和跨度,并将两者结合起来以提取适当长度的文本。

例如:

>>> import re
>>> a = 'ATTAA$At^&atAA-1A+1G+4ATCG'
>>> expr = '[+-]?([0-9]+)[ACGTNacgtn]'
>>> ints = re.findall(expr, a) #returns a list of the integers
>>> spans = [i.span() for i in re.finditer(expr,a)]
>>> newspans = [(spans[i][0],spans[i][1]+(int(indel[i])-1)) for i in range(len(spans))]
>>> newspans
>>> [(14, 17), (17, 20), (20, 26)]

由此产生的元组允许我切掉插入缺失。可能不是最好的语法,但它有效!

4

3 回答 3

2

您可以使用正则表达式替换传递函数作为替换......例如

s = "abcde+3fghijkl-1mnopqr+12abcdefghijklmnoprstuvwxyz"

import re

def dump(match):
    start, end = match.span()
    print s[start:end + int(s[start+1:end])]

re.sub(r'[-+]\d+', dump, s)

#output
# +3fgh
# -1m
# +12abcdefghijkl
于 2012-07-28T14:28:12.030 回答
0

简单的 Perl 模式匹配一​​个整数,后跟该数字的任意字符:

 (\d+)(??{"." x $1})

这很简单,我想你会同意的。例如,这个片段:

my $string = "AtT+3ACGTTT-1AaTTa";

print "Matched $&\n" while $string =~ m{
    ( \d+ )            # capture an integer into $1
    (??{ "." x $1 })   # interpolate that many dots back into pattern
}xg;

愉快地打印出预期的

Matched 3ACG
Matched 1A

编辑

哦,drat,我看到你刚刚添加了 Python 标签,因为我开始编辑。哎呀。好吧,也许这无论如何都会对你有所帮助。

也就是说,如果您实际寻找的是模糊匹配,您可以在其中允许一定数量的插入和删除(编辑距离),那么 Matthew Barnett 的regexPython 库将处理该问题。这似乎不是您正在做的事情,因为插入和删除实际上是在您的字符串中表示的。

但是 Matthew 的库真的很好很有趣,它甚至做了很多 Perl 做不到的事情。:) 它是标准 Pythonre库的直接替代品。

于 2012-07-28T15:20:47.227 回答
0

这不是直接可能的,正则表达式不能像那样“计数”。

但是,如果您使用的编程语言允许将回调作为正则表达式匹配评估器(例如 C#、PHP),那么您可以做的是将正则表达式作为[+-]?([0-9]+)([ACGTNacgtn]+)并且在回调中将尾随字符修剪为所需的长度。

例如对于 C#

var regexMatches = new List<string>();
Regex theRegex = new Regex(@"[+-]?([0-9]+)([ACGTNacgtn]+)");
text = theRegex.Replace(text, delegate(Match thisMatch)
{

    int numberOfInsertsOrDeletes = Convert.ToInt32(thisMatch.Groups[1].Value);
    string trailingString = thisMatch.Groups[2].Value;
    if (numberOfInsertsOrDeletes > trailingString.Length)
    { trailingString = trailingString.Substring(0, numberOfInsertsOrDeletes); }
    regexMatches.Add(trailingString);

    return thisMatch.Groups[0].Value;
});
于 2012-07-28T04:51:54.123 回答