gpt4 book ai didi

ruby - 如何检查文件夹内的多个单词

转载 作者:数据小太阳 更新时间:2023-10-29 08:58:09 25 4
gpt4 key购买 nike

我在名为 words.txt 的文本文件中有一个词,我需要检查这些词中是否有任何一个在我的源文件夹中,该文件夹还包含子文件夹和文件。

我能够使用这段代码将所有单词放入一个数组中:

array_of_words = [] 

File.readlines('words.txt').map do |word|
array_of_words << word
end

而且我还(有点)想出了如何搜索整个源文件夹,包括特定单词的子文件夹和子文件,使用:

Dir['Source/**/*'].select{|f| File.file?(f) }.each do |filepath|
puts filepath
puts File.readlines(filepath).any?{ |l| l['api'] }
end

我不想搜索像 api 这样的一个词,而是想在 Source 文件夹中搜索整个词组(如果可能的话)。

最佳答案

考虑一下:

File.readlines('words.txt').map do |word|
array_of_words << word
end

会将整个文件读入内存,然后将其转换为数组中的单个元素。您可以使用以下方法完成同样的事情:

array_of_words = File.readlines('words.txt')

一个潜在的问题是它不可扩展。如果“words.txt”大于可用内存,您的代码将出现问题,所以要小心。

可以通过多种方式在文件中搜索单词数组,但我始终发现使用正则表达式最简单。 Perl 有一个名为 Regexp::Assemble 的很棒的模块,可以轻松地将单词列表转换为非常有效的模式,但 Ruby 缺少这种功能。请参阅“Is there an efficient way to perform hundreds of text substitutions in Ruby?”了解我过去为解决此问题而整理的一种解决方案。

Ruby 确实有 Regexp.union 但它只是部分帮助。

words = %w(foo bar)
re = Regexp.union(words) # => /foo|bar/

生成的模式有表达式的标志,所以你必须小心地将它插入到另一个模式中:

/#{re}/ # => /(?-mix:foo|bar)/

(?-mix: 会给你带来问题,所以不要那样做。而是使用:

/#{re.source}/ # => /foo|bar/

这将生成模式并像我们预期的那样运行。

不幸的是,这也不是一个完整的解决方案,因为换句话说,这些词可以作为子字符串找到:

'foolish'[/#{re.source}/] # => "foo"

解决这个问题的方法是围绕模式设置单词边界:

/\b(?:#{re.source})\b/ # => /\b(?:foo|bar)\b/

然后寻找整个单词:

'foolish'[/\b(?:#{re.source})\b/] # => nil

更多信息可在 Ruby 的 Regexp 中找到。文档。

一旦您有了想要使用的模式,搜索起来就变得更简单了。 ruby 有 Find类,这使得递归搜索文件目录变得容易。该文档介绍了如何使用它。

或者,您可以使用 Dir 拼凑您自己的方法类(class)。同样,它在文档中有使用它的示例,但我通常使用 Find。

当读取您正在扫描的文件时,我建议使用 foreach 逐行读取文件。 File.readFile.readlines不可可扩展的,当 Ruby 尝试将大文件读入内存时,它们会使您的程序行为不稳定。相反,foreach 将生成可扩展性更强、运行速度更快的代码。有关详细信息,请参阅“Why is "slurping" a file not a good practice?”。

使用上面的链接,您应该能够快速地将一些东西放在一起,这些东西将高效且灵活地运行。


这段未经测试的代码应该可以帮助您入门:

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

它将输出它正在读取的文件,以及“true”或“false”是否命中列表中的某个单词。

由于 readlinesread,它不可扩展,如果任何文件很大,它可能会严重减速。同样,请参阅上面“slurp”链接中的注意事项。

关于ruby - 如何检查文件夹内的多个单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43770139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com