Considérez ceci:
File.readlines('words.txt').map do |word|
array_of_words << word
end
va lire le fichier en mémoire, puis le convertir en éléments individuels dans un tableau. Vous pouvez accomplir la même chose en utilisant:
array_of_words = File.readlines('words.txt')
Un problème potentiel est son non scalable. Si "words.txt" est plus grand que la mémoire disponible, votre code aura des problèmes alors soyez prudent.
La recherche d'un tableau de mots dans un fichier peut se faire de plusieurs façons, mais j'ai toujours trouvé qu'il était plus facile d'utiliser une expression régulière. Perl a un excellent module appelé Regexp :: Assemble qui facilite la conversion d'une liste de mots en un modèle très efficace, mais Ruby manque ce genre de fonctionnalité. Voir "Is there an efficient way to perform hundreds of text substitutions in Ruby?" pour une solution que j'ai rassemblée dans le passé pour vous aider.
Ruby a Regexp.union
mais ce n'est qu'une aide partielle.
words = %w(foo bar)
re = Regexp.union(words) # => /foo|bar/
Le modèle généré a des drapeaux pour l'expression, donc vous devez être prudent avec interpoler dans un autre motif:
/#{re}/ # => /(?-mix:foo|bar)/
(?-mix:
vous causer des problèmes afin de ne pas le faire. Au lieu de cela, utilisez:
/#{re.source}/ # => /foo|bar/
qui générera le motif et se comportera comme prévu.
Malheureusement, ce n'est pas une solution complète soit, parce que les mots peuvent être trouvés comme sous-chaînes en d'autres termes:
'foolish'[/#{re.source}/] # => "foo"
La façon de travailler autour de c'est de mettre en mot-frontières autour du modèle:
/\b(?:#{re.source})\b/ # => /\b(?:foo|bar)\b/
qui ont l'air puis des mots entiers pour:
'foolish'[/\b(?:#{re.source})\b/] # => nil
Plus d'informations sont disponibles dans la documentation Regexp de Ruby.
Une fois que vous avez un motif que vous souhaitez utiliser, la recherche devient plus simple. Ruby a la classe Find, ce qui facilite la recherche récursive de répertoires dans les répertoires. La documentation couvre comment l'utiliser.
Alternativement, vous pouvez bricoler votre propre méthode en utilisant la classe Dir. Encore une fois, il a des exemples dans la documentation pour l'utiliser, mais je vais généralement avec Find.
Lors de la lecture des fichiers que vous numérisez, je recommande d'utiliser foreach
pour lire les fichiers ligne par ligne. File.read
et File.readlines
sont pas évolutive et peut rendre votre programme se comporter de façon erratique comme Ruby essaie de lire un gros fichier en mémoire. Au lieu de cela, foreach
se traduira par un code très évolutif qui s'exécute plus rapidement. Voir "Why is "slurping" a file not a good practice?" pour plus d'informations. En utilisant les liens ci-dessus, vous devriez être capable de mettre rapidement quelque chose ensemble qui fonctionnera efficacement et sera flexible.
Ce code non testé devrait vous aider à démarrer:
WORD_ARRAY = File.readlines('words.txt').map(&:chomp)
WORD_RE = /\b(?:#{Regexp.union(WORD_ARRAY).source}\b)/
Dir['Source/**/*'].select{|f| File.file?(f) }.each do |filepath|
puts "#{filepath}: #{!!File.read(filepath)[WORD_RE]}"
end
Il affichera le fichier, il est la lecture, et « vrai » ou « faux » s'il y a un coup de trouver un des mots dans la liste.
Ce n'est pas évolutif en raison de readlines
et read
et pourrait souffrir d'un grave ralentissement si l'un des fichiers est énorme. Encore une fois, voir les mises en garde dans le lien "slurp" ci-dessus.
Est-ce que tu dois le faire dans ruby? L'outil en ligne de commande 'egrep' pourrait le faire beaucoup plus facilement via quelque chose comme' egrep -r '(api | function | method) "*' ... – Brian
Hey @Brian, oui, malheureusement, il doit être en ruby. –