簡體   English   中英

正則表達式在匹配和匹配順序的字符串上

[英]RegEx on a string for a match AND a match REGARDLESS of order

我正在編寫一個Java程序,一次搜索15個字符的DNA序列,找到C和G出現次數最多的部分。我認為檢查整個DNA序列中包含15個子字符串的任何區域的速度最快。完全由C和G組成,如果不存在,則尋找具有14個C和G以及1 A或T的子串。然后,如果沒有出現,則返回13 CG和2 AT等。

試圖找到一個正則表達式解決方案對我來說已經很困難。 我已經使用此代碼提出了一個測試用例,但是我無法使RegEx正常工作。 我認為語法可能是錯誤的,我從未在Java中使用過RegExes。 抱歉,我可能可以弄清楚語法,我只需要正則表達式本身匹配正確內容的幫助即可。

public class DNAChecker{

     public static void main(String []args){
        String checkThis= "ggccggccaggccgg";

        if (checkThis.matches( “(?=.*[CcGg]{14})(?=.*[AaTt]{1})” ) ) {
            System.out.println("This program works.");
        } else {
            System.out.println("This program doesn't work.");
        }
     }
}

我的理解方式以及我在相關線程中所看到的,如果可以使用正則表達式來完成,那么我至少會對此有所了解。 現在我正在考慮,我不認為這可以確保總的匹配長度為15個字符...即,如果checkThis的長度超過15個字符,並且總共有14個CG和1個AT,則不是連續地,這仍然是正確的。 因此,xxxxggccggxxccaggccggxxxxxx是正確的。 使用.contains而不是.matches是否可以確保長度限制?

無論如何,像這樣的單行RegEx甚至比計算每個子字符串的C和G還要快嗎? 我還沒有上算法課。

請記住,該程序的最終形式將接受可變長度的字符串,並搜索長度為n的子字符串,而不是每次都搜索15。 (我知道如何處理這些要求,因此無需告訴我有關Scanner或參數是如何工作的!)我只是一個RegEx新手,試圖使用Jedi級RegEx東西...如果您可以為我推薦一本書,成為RegExes的向導,那將是激進的。 預先非常感謝您的回復!

正則表達式是所有語言中最誘人的功能之一。 但是,僅因為它們既酷又性感並且看起來非常強大,並不意味着它們是正確的工具。 對於這樣的事情,一個簡單的狀態機就足夠了,而且速度可能會更快。 下面的代碼查找僅包含cg的最長子字符串,並且可以通過將它們添加到集合中來輕松修改以保留多個子字符串。

    String data = "acgtcgcgagagagggggcccataatggg";
    int    longestPos = 0;
    int    longestLen = 0;
    int p=-1;
    for (int i=0; i<data.length(); i++)
    {
        char c = data.charAt(i);
        if (c == 'c' || c == 'g')  // Is this the droid you're looking for?
        {
            if (p==-1)  // Are we not yet in an interesting string?
                p = i;  // If so, save the position of this start of substring.
        }
        else  // Not a c or g
        {
            if (p != -1 && i-p > longestLen)  // Are we in an interesting string longer than the previous longest?
            {
                longestPos = p;     // Save the starting position
                longestLen = i-p;   // Save the length
            }
            p = -1;   // We're no longer inside an interesting string
        }
    }

    // Handle the case where the last substring was 'interesting'
    if (p != -1 && i-p > longestLen)
    {
        longestPos = p;     // Save the starting position
        longestLen = i-p;   // Save the length
    }

    System.out.printf("Longest string is at position %d for length %d", longestPos, longestLen);

對於“在不適用的地方使用正則表達式”的規范響應,請參閱此帖子

我不確定我是否正確理解了您的問題,因此假設您要查找由c s和g s后跟at組成的最長字符序列。

我進一步假設您的輸入字符串僅包含那些字符。

因此,您可以嘗試使用Pattern.compile(regex).matcher(input).find()來獲取所有匹配的組。 然后按長度對它們進行排序,即可得到最長的序列。

為此,可以使用以下正則表達式:( (?i)([cg]+[at])(i?)使表達式不區分大小寫)。

例:

String input = "ccgccgCggatccgCATccggcccgggggtatt";

List<String> sequences = new ArrayList<>();

//find the sequences
Matcher m = Pattern.compile("(?i)([cg]+[at])").matcher( input );
while( m.find() ) {
  sequences.add( m.group().toLowerCase() );
}

//sort by descending length
Collections.sort( sequences, new Comparator<String>() {
  public int compare( String lhs, String rhs ) {
    //switch arguments for descending sort
    return Integer.compare( rhs.length(), lhs.length());
  }
});

System.out.println( sequences );

輸出應為: [ccggcccgggggt, ccgccgcgga, ccgca]

如果您只想允許這些序列的特定長度,則需要更改正則表達式:
(?i)(?<=^|[^cg])([cg]{10,15}[at])

變化:

(?<=^|[^cg])表示該序列必須在輸入的開頭或cg之外的任何內容之前。 要匹配更長序列的一部分, gcga ,從cccgcga刪除cccgcga ,只需從正則表達式中刪除它即可。

[cg]{10,15}表示cs和gs的序列必須在10到15個字符之間,例如,如果不使用(?<=^|[^cg]) 要使用精確的長度(例如15個字符),請使用上述條件,並將此條件更改為[cg]{15}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM