# Regexing a file's contents without reading the whole thing?

**URL:** https://rubytalk.org/t/regexing-a-files-contents-without-reading-the-whole-thing/56432
**Category:** ruby-talk
**Created:** [30 November 2009 20:32 UTC](https://rubytalk.org/t/regexing-a-files-contents-without-reading-the-whole-thing/56432 "2009-11-30T20:32:12Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Roger\_Pack4](https://avatars.discourse-cdn.com/v4/letter/r/bb73d2/32.png) [@Roger\_Pack4](https://rubytalk.org/u/Roger_Pack4)
#### Post date: [30 November 2009 20:32 UTC](https://rubytalk.org/t/regexing-a-files-contents-without-reading-the-whole-thing/56432/1 "2009-11-30T20:32:12Z")

</div>

I see that it is possible currently to parse through a file without  
reading the whole thing into RAM, a la

a = File.open('a', 'r')  
a.lines{|line|  
&nbsp;&nbsp;if line =~ /some regex/  
&nbsp;&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;end  
}

But what if I can to do something like  
a = File.read('a').scan /some regex/

is that possible?

Thanks.  
-r

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

### Author: ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)
#### Post date: [30 November 2009 20:54 UTC](https://rubytalk.org/t/regexing-a-files-contents-without-reading-the-whole-thing/56432/2 "2009-11-30T20:54:46Z")

</div>

Roger Pack wrote:

> I see that it is possible currently to parse through a file without  
> reading the whole thing into RAM, a la
> 
> a = File.open('a', 'r')  
> a.lines{|line|  
> &nbsp;&nbsp;if line =~ /some regex/  
> &nbsp;&nbsp;&nbsp;&nbsp;...  
> &nbsp;&nbsp;end  
> }
> 
> But what if I can to do something like  
> a = File.read('a').scan /some regex/
> 
> is that possible?
> 
> Thanks.  
> -r

File.open('/usr/share/dict/words').grep /ruby/i

> **···**
>
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

### Author: ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)
#### Post date: [1 December 2009 12:59 UTC](https://rubytalk.org/t/regexing-a-files-contents-without-reading-the-whole-thing/56432/3 "2009-12-01T12:59:10Z")

</div>

If you know that matches will never cross line breaks you can do

a =   
File.foreach("a") do |line|  
&nbsp;&nbsp;line.scan /regex/ do |m|  
&nbsp;&nbsp;&nbsp;&nbsp;a \<\< m  
&nbsp;&nbsp;end  
&nbsp;&nbsp;# alternative:  
&nbsp;&nbsp;a.concat(line.scan(/regex/))  
end

If matches can cross line breaks the whole store becomes more  
complicated and your solution with File.read is probably the simplest  
way to do it (if files aren't too large).

Kind regards

robert

> **···**
>
> 2009/11/30 Roger Pack \<rogerpack2005@gmail.com\>:
> 
> > I see that it is possible currently to parse through a file without  
> > reading the whole thing into RAM, a la
> > 
> > a = File.open('a', 'r')  
> > a.lines{|line|  
> > if line =~ /some regex/  
> > ...  
> > end  
> > }
> > 
> > But what if I can to do something like  
> > a = File.read('a').scan /some regex/
> > 
> > is that possible?
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

### Author: ![Caleb\_Clausen1](https://avatars.discourse-cdn.com/v4/letter/c/8dc957/32.png) [@Caleb\_Clausen1](https://rubytalk.org/u/Caleb_Clausen1)
#### Post date: [2 December 2009 01:33 UTC](https://rubytalk.org/t/regexing-a-files-contents-without-reading-the-whole-thing/56432/4 "2009-12-02T01:33:26Z")

</div>

The library which makes this possible is sequence. I'm coding this  
from memory, so I'm likely to get something wrong, but the equivalent  
in sequence looks more or less like this:

require 'rubygems'  
require 'sequence'  
require 'sequence/file'

seq=Sequence.new(File.open('a'))  
seq.scan\_until(/some regex/)

Keep the following in mind:  
1) Sequence#scan works like StringScanner#scan, not String#scan.  
2) The pattern to be matched must have a max length (4k by default, I  
think; it can be changed).  
3) If your pattern is guaranteed to not contain a nl, you're better  
off with readline, as robert said.

> **···**
>
> On 11/30/09, Roger Pack \<rogerpack2005@gmail.com\> wrote:
> 
> > I see that it is possible currently to parse through a file without  
> > reading the whole thing into RAM, a la
> > 
> > a = File.open('a', 'r')  
> > a.lines{|line|  
> > &nbsp;&nbsp;if line =~ /some regex/  
> > &nbsp;&nbsp;&nbsp;&nbsp;...  
> > &nbsp;&nbsp;end  
> > }
> > 
> > But what if I can to do something like  
> > a = File.read('a').scan /some regex/
> > 
> > is that possible?
