2016-05-21 12 views
2

In Anbetracht der SaiteRubin Regex in Folge einzigartige Charaktere

aabbaacceeeeeaa

Ich versuche, einen regulären Ausdruck zu entwickeln, die Teil erfassen wird, die drei eindeutige Zeichen beliebiger Menge enthalten.

["aabbaacc", "bbaacc", "aacceeeeaa" "cceeeeaa"]. 

Ich habe versucht, so etwas wie

/[(\w)\1+]/ or /[(\w)(?!\1)]/ 

Ich kenne diese unvollständig sind. Ich bin mir nicht sicher, ob ich auf dem richtigen Weg bin oder nicht.

aber ich bin mir nicht sicher, wie man bereits passende Charaktere ausschließt, oder zumindest kann ich nicht scheinen zu verwenden?! richtig.

+0

Nicht klar, was Sie tun. – sawa

Antwort

3

Viel Glück mit dem regulären Ausdruck, aber wenn Sie benötigen einen Backup-Plan, ....

def pull_subs(str, n) 
    arr = str.chars 
    (n..str.size).each_with_object([]) { |i,a| arr.each_cons(i) { |b| 
    a << b.join if b.uniq.size == n } } 
end 

str = "aabbaacceeeeeaa" 

pull_subs(str, 3) 
    #=> ["baac", "acce", "bbaac", "baacc", "aacce", "accee", "abbaac", "bbaacc", 
    # "aaccee", "acceee", "aabbaac", "abbaacc", "aacceee", "acceeee", "ceeeeea", 
    # "aabbaacc", "aacceeee", "acceeeee", "cceeeeea", "ceeeeeaa", "aacceeeee", 
    # "acceeeeea", "cceeeeeaa", "aacceeeeea", "acceeeeeaa", "aacceeeeeaa"] 
pull_subs(str, 2) 
    #=> ["ab", "ba", "ac", "ce", "ea", "aab", "abb", "bba", "baa", "aac", "acc", 
    # "cce", "cee", "eea", "eaa", "aabb", "abba", "bbaa", "aacc", "ccee", 
    # "ceee", "eeea", "eeaa", "aabba", "abbaa", "cceee", "ceeee", "eeeea", 
    # "eeeaa", "aabbaa", "cceeee", "ceeeee", "eeeeea", "eeeeaa", "cceeeee", 
    # "eeeeeaa"] 
pull_subs(str, 4) 
    #=> ["baacce", "bbaacce", "baaccee", "abbaacce", "bbaaccee", "baacceee", 
    # "aabbaacce", "abbaaccee", "bbaacceee", "baacceeee", "aabbaaccee", 
    # "abbaacceee", "bbaacceeee", "baacceeeee", "aabbaacceee", "abbaacceeee", 
    # "bbaacceeeee", "baacceeeeea", "aabbaacceeee", "abbaacceeeee", 
    # "bbaacceeeeea", "baacceeeeeaa", "aabbaacceeeee", "abbaacceeeeea", 
    # "bbaacceeeeeaa", "aabbaacceeeeea", "abbaacceeeeeaa", "aabbaacceeeeeaa"] 
4

Es ist unmöglich, es mit scan zu tun, weil die erwarteten Teilüberlappen. Der beste Weg, dies zu tun, ist die Verwendung von Indizes.

Es ist schwierig, eine Regex zu verwenden, um Übereinstimmungen auszuschließen, die in der Mitte aufeinanderfolgender identischer Buchstaben beginnen.

s = "aabbaacceeeeeaa" 

(1..s.length).map do 
    |i| 
    (s[i] != s[i + 1] || nil) && 
    /(.)\1*+(.)(?:\1|\2)*+(.)(?:\1|\2|\3)*/.match(s, i - 1)&.[](0) 
end.compact 
# => ["aabbaacc", "bbaacc", "aacceeeeeaa", "cceeeeeaa"] 
+0

Nizza. Gespielt mit deiner Regex [hier] (http://rubular.com/r/8ZvHLdv1jV) (Gruppe 2). –