在与正则表达式匹配的文本文件中查找行

时间:2011-05-14 15:37:31

标签: ruby regex

任何人都可以解释如何在Ruby中使用正则表达式来仅返回字符串的匹配项。

例如,如果代码读入包含一系列名称的.txt文件:

John Smith
James Jones
David Brown
Tom Davidson
etc etc

..并且匹配的单词输入为'ohn',然后它将返回'John Smith',但没有其他名称。

4 个答案:

答案 0 :(得分:24)

以下是一些不同的方法来获取您的目标。

首先请注意,我正在使用更惯用的方式编写用于从文件中读取行的代码。 Ruby的IO和文件库使得在一个漂亮整洁的软件包中打开,读取和关闭文件变得非常容易。

File.each_line('file.txt') do |li|
  puts li if (li['ohn'])
end

在行中的任何地方寻找'ohn',但不会打扰正则表达式。

File.each_line('file.txt') do |li|
  puts li if (li[/ohn/])
end

查找相同的字符串,只使用正则表达式到达那里。在功能上它与第一个例子相同。

File.each_line('file.txt') do |li|
  puts li if (li[/ohn\b/])
end

这是寻找以'ohn'结尾的名字的一种更聪明的方式。它使用正则表达式,但也指定模式必须出现在单词的末尾。 \b表示“字边界”。

此外,在阅读文件时,始终要考虑正在阅读的文件是否可能超过应用程序可用的RAM,这一点非常重要。一次通过将整个文件读入内存很容易,然后从RAM处理它,但是如果你超出了可用的物理RAM,你可以瘫痪或杀死你的应用程序或机器。


  

您知道其他答案所显示的代码是否实际上是将整个文件加载到RAM中,或者是否通过从readlines函数流式传输到select函数进行优化?

来自IO#readlines文档:

  

将name指定的整个文件读取为单独的行,并返回数组中的这些行。行由sep分隔。

另一个考虑因素是在大量批量读取期间的内存分配。即使你有足够的RAM,你也可以遇到语言在读入数据时窒息的情况,发现它没有为变量分配足够的内存,并且在抓取更多内容时必须暂停。该循环重复,直到加载整个文件。

多年以前,当我将一个非常大的数据文件加载到HP最大的迷你版本的Perl应用程序中时,我对此变得敏感。该应用程序会定期暂停几秒钟,我无法弄清楚原因。我进入了调试器,无法找到问题。最后,通过使用旧式打印语句跟踪运行,我将暂停分离为文件“slurp”。我有足够的内存和足够的处理能力,但Perl没有分配足够的内存。我逐渐切换到阅读,应用程序飞过它的处理。像Perl一样,Ruby具有良好的I / O,并且在逐行读取时可以非常快速地读取大文件。我从来没有找到一个很好的理由来诋毁文本文件,除非我可以将内容分布在多行中,但这种情况并不常见。

答案 1 :(得分:15)

也许我没有完全理解这个问题,但你可以这样做:

File.readlines("path/to/file.txt").select { |line| line =~ /ohn/ }

获取符合条件的所有行的数组。

答案 2 :(得分:11)

query = 'ohn'
names = File.readlines('names.txt')
matches = names.select { |name| name[/#{query}/i] }
#=> ["John Smith"]

如果您希望查询区分大小写,请删除正则表达式末尾的i

答案 3 :(得分:2)

旧问题,但File.readlines("names.txt").grep /#{query}/i 也可用于搜索字符串列表

select
  z.szratnd_attending_ind,
  sum(f.sfrstcr_credit_hr) as attending_hrs
from szratnd z
join sfrstcr f on  f.szratnd_pidm      = z.szratnd_pidm
               and f.szratnd_term_code = z.szratnd_term_code
               and f.szratnd_crn       = z.szratnd_crn
               and f.szratnd_rsts_code = z.szratnd_rsts_code
where z.szratnd_pidm = 264185
group by szratnd_attending_ind;