2010-12-20 10 views
2

ich eine Reihe von Wort haben: hello, poison, world, search, echo ... Und ich habe einige Briefe e, h, o Jetzt habe ich brauche alle Wörter zu finden, die diese Buchstaben enthält. Wie search, echo für e, h, oRegulärer Ausdruck: wenn drei Buchstaben enthalten sind

kann ich diese Art und Weise suchen:

words = %w[hello poison world search echo] 
matched = words.select do |w| 
    %w[e,h,o].all?{ |l| w =~ /#{l}/ } 
end 

Das Problem ist, dass, wenn Buchstaben o, o, o sind, oder l, b, l Diese Suche return true wird für Wörter wie open oder boil, aber ich brauche Wörtern suchen das schließt drei o oder zwei von l und ein b

UPD:

leters = "abc" 
words.select{ |w| w.count(letters) >= 3 } 

upd 2

Bad Lösung, Beispiel:

"lllllll".count("lua") #=> 5 
+0

Wie viele Wörter Wenn Sie eine gute Leistung über ein? ganzes Wörterbuch, die Lösungen sind unterschiedlich –

+0

Wie groß ist Ihr Text? Und müssen Sie mehrere 3-Buchstaben-Sätze dagegen laufen? –

+0

ungefähr 500-1000 Wörter (es ist Array, acctually). Und ich werde mehrere laufen lassen Sätze (20-30 jedes Mal) – fl00r

Antwort

1

Sind Sie sicher, dass Sie eine Regexp möchten? Zeichenfolgen unterstützen das Zählen von Werten in ihnen, Sie könnten diese Funktion verwenden. Etwas wie folgt aus:

words = ["pool", "tool", "troll", "lot"] 
letters = "olo" 

#find how many of each letter we need 
counts = {} 
letters.each { |v| counts[v] = letters.count(v) } 

#See if a given work matches all the counts 
# accumulated above 
res = words.select do |w| 
    counts.keys.inject(true) do |match, letter| 
     match && (w.count(letter) == counts[letter]) 
    end 
end 
+0

Warum können wir nicht einfach 'words.select {| w | verwenden w.count (Buchstaben)} ' – fl00r

+0

Got it. Ich mag diesen Weg. Danke! – fl00r

1

Es ist wahrscheinlich am besten nicht regulären Ausdrücke für diese zu verwenden, aber es kann getan werden:

Alle drei Buchstaben anders:

/^(?=.*a)(?=.*b).*c/ 

Zwei gleich und ein anderes:

/^(?=.*a.*a).*b/ 

Alle drei gleich:

/^.*a.*a.*a/ 
+0

Wie kann ich das ohne reguläre Ausdrücke lösen? – fl00r

+0

@floor: Zählen Sie die Häufigkeit jedes Buchstabens in Ihrem Ziel drei Buchstaben, und überprüfen Sie dann für jeden Buchstaben, dass es mindestens so oft in dem Wort vorkommt, das Sie testen. –

1

Betrachten Sie das Wort zu modifizieren (so dass es mit jeder Kontrolle kleiner wird).

words = %w(fooo for find o ooo) 
matched = words.select do |orig| 
    # note: str.gsub! returns nil if nothing was replaced 
    w = orig.clone 
    %w(o o o).all?{ |l| w.gsub!(/^(.*)(#{l})(.*)$/, '\1\3') } 
end 
0

Sieht verrückt, aber es funktioniert:

leters = "abc" 
words.select{ |w| w.count(letters) >= 3 } 

Aber es ist nicht mit kyrillischen Buchstaben arbeiten :(

+0

Verallgemeinert: 'words.select {| w | w.count (Buchstaben)> = letters.size} ' –

+1

ein ernstes Problem:' "lllll".count (alo) # => 5' :( – fl00r

+0

Kyrillische Buchstaben mit 'jcount' – fl00r

Verwandte Themen