# Text lines manipulation

**URL:** <https://www.ruby-forum.com/t/text-lines-manipulation/174677>\
**Category:** Ruby\
**Created:** [August 31, 2009, 11:46am UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677 "2009-08-31T11:46:51Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![georgeuoa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/7ab992/32.png) [@georgeuoa](https://www.ruby-forum.com/u/georgeuoa)\
**Post date:** [August 31, 2009, 11:46am UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677/1 "2009-08-31T11:46:51Z")

</div>

have a set of lines like shown below:  
#set1  
1-3  
3-5  
6-7  
#set2  
20-23  
450-550  
#set3  
1-50  
20-56

The idea is to read each of the lines associated with each set and do  
some manipulation?

any easy way of doing this?

Thanks

---

<div class="post-metadata">

**Author:** ![georgeuoa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/7ab992/32.png) [@georgeuoa](https://www.ruby-forum.com/u/georgeuoa)\
**Post date:** [August 31, 2009, 12:06pm UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677/2 "2009-08-31T12:06:54Z")

</div>

Hi,

Am Montag, 31. Aug 2009, 18:46:53 +0900 schrieb George G.:

> 20-56
> 
> The idea is to read each of the lines associated with each set and do  
> some manipulation?

Untested:

file.each\_line { |l|  
l.chomp!  
case l  
when /^#/ then set = $’  
else  
do\_sth\_with set, l  
end  
}

Bertram

---

<div class="post-metadata">

**Author:** ![georgeuoa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/7ab992/32.png) [@georgeuoa](https://www.ruby-forum.com/u/georgeuoa)\
**Post date:** [August 31, 2009, 1:33pm UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677/3 "2009-08-31T13:33:18Z")

</div>

Thanks Betram

This seems to work for me,  
dont know whether its efficient or there is a better implementation

file.each\_line do |line|  
line.chomp!  
case line  
when /^\>/ then set = $’  
puts set  
else

```
   re1='(\\d+)' # Integer Number 1
   re2='(-)' # Any Single Character 1
   re3='(\\d+)' # Integer Number 2

 re=(re1+re2+re3)
 m=Regexp.new(re,Regexp::IGNORECASE);
   if m.match(line)
      int1 = m.match(line)[1];
      c1 = m.match(line)[2];
      int2 = m.match(line)[3];
      puts int1<< c1 << int2
  end
end

```

end

Bertram S. wrote:

> Hi,
> 
> Am Montag, 31. Aug 2009, 18:46:53 +0900 schrieb George G.:
> 
> > 20-56
> > 
> > The idea is to read each of the lines associated with each set and do  
> > some manipulation?
> 
> Untested:
> 
> file.each\_line { |l|  
> l.chomp!  
> case l  
> when /^#/ then set = $’  
> else  
> do\_sth\_with set, l  
> end  
> }
> 
> Bertram

---

<div class="post-metadata">

**Author:** ![georgeuoa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/7ab992/32.png) [@georgeuoa](https://www.ruby-forum.com/u/georgeuoa)\
**Post date:** [August 31, 2009, 4:45pm UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677/4 "2009-08-31T16:45:37Z")

</div>

Hi –

On Mon, 31 Aug 2009, Bertram S. wrote:

> Hi,
> 
> Am Montag, 31. Aug 2009, 20:33:19 +0900 schrieb George G.:
> 
> > ```
> > m=Regexp.new(re,Regexp::IGNORECASE);
> > if m.match(line)
> > int1 = m.match(line)[1];
> > c1 = m.match(line)[2];
> > int2 = m.match(line)[3];
> > puts int1<< c1 << int2
> > end
> > 
> > ```

To the OP: definitely lose the semi-colons 🙂

> if line =~ /(\d+)(-)(\d+)/i then  
> int1 = $1  
> c1 = $2  
> int2 = $3  
> puts int1 + c1 + int2  
> end
> 
> This is for the not faint-hearted:
> 
> int1, c1, int2 = \*$~.captures

It’s a little less formidable without the \*, which should be OK. A  
mixed solution:

int1, c1, int2 = $1, $2, $3

or use Regexp#match and save the match explicitly.

match = m.match(line)

if match  
int1, c1, int2 = match.captures  
end

or similar.

David

–  
David A. Black / Ruby Power and Light, LLC / [http://www.rubypal.com](http://www.rubypal.com)  
Ruby/Rails training, mentoring, consulting, code-review  
Latest book: The Well-Grounded Rubyist ([The Well-Grounded Rubyist](http://www.manning.com/black2))

September Ruby training in NJ has been POSTPONED. Details to follow.

---

<div class="post-metadata">

**Author:** ![georgeuoa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/7ab992/32.png) [@georgeuoa](https://www.ruby-forum.com/u/georgeuoa)\
**Post date:** [September 1, 2009, 3:31am UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677/5 "2009-09-01T03:31:26Z")

</div>

Hi,

Am Montag, 31. Aug 2009, 23:42:43 +0900 schrieb David A. Black:

> On Mon, 31 Aug 2009, Bertram S. wrote:
> 
> > int1, c1, int2 = \*$~.captures
> 
> It’s a little less formidable without the \*, which should be OK. A  
> mixed solution:
> 
> int1, c1, int2 = $1, $2, $3

There’s so much more nice things you can do. I cannot hold it back  
any more.

h = {}  
…  
h[set] ||= []  
h[set].push int1.to\_i…int2.to\_i

And so on. Isn’t it sweet?

Bertram

---

<div class="post-metadata">

**Author:** ![georgeuoa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/7ab992/32.png) [@georgeuoa](https://www.ruby-forum.com/u/georgeuoa)\
**Post date:** [August 31, 2009, 4:33pm UTC](https://www.ruby-forum.com/t/text-lines-manipulation/174677/6 "2009-08-31T16:33:55Z")

</div>

Hi,

Am Montag, 31. Aug 2009, 20:33:19 +0900 schrieb George G.:

> ```
> m=Regexp.new(re,Regexp::IGNORECASE);
> if m.match(line)
> int1 = m.match(line)[1];
> c1 = m.match(line)[2];
> int2 = m.match(line)[3];
> puts int1<< c1 << int2
> end
> 
> ```

After `m.match(line)’ the match is stored in the $~ global  
variable. You don’t need to execute it three more times.

$~[1] is equivalent to $1.

The `<<' operator modifieds the string`int1’. Better is here the  
operator `+’.

It’s sure a matter of taste but in general shorter code is easier  
to read.

if line =~ /(\d+)(-)(\d+)/i then  
int1 = $1  
c1 = $2  
int2 = $3  
puts int1 + c1 + int2  
end

This is for the not faint-hearted:

int1, c1, int2 = \*$~.captures

Bertram
