我应该如何结合这些正则表达式?

时间:2011-07-11 15:39:21

标签: regex perl

 $syb =~ s/(at{3,6})/\U$1/gi;

 $syb =~ s/(aat{2,5})/\U$1/gi;

 $syb =~ s/(aaat{1,4})/\U$1/gi;

 $syb =~ s/(aaaat{0,3})/\U$1/gi;

 $syb =~ s/(aaaaat{0,2})/\U$1/gi;

 $syb =~ s/(a{4,7})/\U$1/gi;

 $syb =~ s/(aaaaaat)/\U$1/gi;

 $syb =~ s/(t{4,7})/\U$1/gi;

有什么方法可以将所有这些正则表达式合二为一吗?在同一个字符串上使用这么多正则表达式是不好的做法吗?如果$ syb是aaatcgacgatcgatcaatttcgaaaaaggattttttatgcacgcacggggattaaaa,最终结果应该是 正则表达式应该成功 AAATcgacgatcgatcAATTTcgAAAAAggATTTTTTatgcacgcacggggattAAAA

我的正则表达式的一个问题是它们将aaaatttt匹配为两个单独的匹配并输出AAAATTTT。我也需要解决这个问题。

我有一串A的C's T和G存储在$ syb中。我想把字符串的任何部分大写,其中有一组A的后跟T,只有A或只是T(T后跟A不应该),大写部分可能不短于4且不长于7

2 个答案:

答案 0 :(得分:5)

这是一个艰难的。我认为这可能有用:

s/((?<!a)a|(?<!a|t)t)((?<!t)\1|t){3,6}(?!\2|t)/\U$&/gi

基本上,我正在做的是:

  1. 获取a之前没有a。或t前面没有at
    • ((?<!a)a|(?<!a|t)t)
  2. 在第一场比赛中获得3-6分,或t's之前没有t
    • ((?<!t)\1|t){3,6}
  3. 确保序列中的最后一项或t后面没有。
    • (?!\2|t)/
  4. 和perl代码:

    $syb = "aaatcgacgatcgatcaatttcgaaaaaggattttttatgcacgcacggggattaaaaactgaaaattttactgaaaaaaaasttttttts";
    $syb =~ s/((?<!a)a|(?<!a|t)t)((?<!t)\1|t){3,6}(?!\2|t)/\U$&/gi;
    print $syb;
    

    编辑从qtax获取队列我已从我的队列中删除捕获组并从他的角色中删除:

    s/(?:(?<!a)a|(?<!a|t)t)(?:(?<!t)a|t){3,6}(?!(?<=a)a|t)/\U$&/gi
    

    编辑:将正则表达式减少5个字符。

    s/(?<!a|t(?=t))(?:a|t(?!a)){3,6}(?:a(?!a)|t)(?!t)/\U$&/gi
    

    与提交

    s/
    # Look behind for a char not an 'a' nor a 't' followed by a 't'
    (?<!a|t(?=t))
    # Capture 3-6 'a's or 't's not followed by 'a's
    (?:a|t(?!a)){3,6}
    # Capture an 'a' not followed by an 'a', or a 't'
    (?:a(?!a)|t)
    #make sure none of this is followed by a 't'.
    (?!t)
    /\U$&/gix;
    

答案 1 :(得分:3)

如聊天中所述,如果可能的组合长于7,则应忽略它,并且不替换它的任何部分。 See this chat

我的后期参考免费解决方案:

s/
(?:(?<!a)a|(?<!t|a)t)
(?:(?<=a)a|(?<=a)t|(?<=t)t){3,6}
(?!(?<=a)a|(?<=a)t|(?<=t)t)
/\U$&/gix;

有一些评论:

s/
# match the first [at] only if not part of a valid sequence
(?:(?<!a)a|(?<!t|a)t)
# only match the allowed transitions: a->a, a->t, t->t
(?:(?<=a)a|(?<=a)t|(?<=t)t){3,6}
# ending can not be a valid transition: negate the above
(?!(?<=a)a|(?<=a)t|(?<=t)t)
/\U$&/gix;

更新:应用Jacob的缩短创意,这里有一些评论:

s/
# match the first a or t only if it's not part of a valid sequence
(?:(?<!a)a|(?<!t|a)t)
# only match the allowed transitions: a->a, a->t, t->t
# (t can follow any of the previous chars, so no need to check it)
(?:(?<=a)a|t){3,6}
# ending can not be a valid transition: negate the above
(?!(?<=a)a|t)
/\U$&/gix;

编辑:一种不那么有效的解决方案:

s/(a+t*|t+)/(length $1 >= 4 && length $1 <= 7)? "\U$1": $1/gie;

PS:感谢OP提供比平时更有趣的正则表达式问题。 :)