# Need help bringing select array lines together

**URL:** <https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807>\
**Category:** ruby-talk\
**Created:** [26 May 2011 16:30 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807 "2011-05-26T16:30:36Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paul22](https://avatars.discourse-cdn.com/v4/letter/p/e68b1a/32.png) [@Paul22](https://rubytalk.org/u/Paul22)\
**Post date:** [26 May 2011 16:30 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/1 "2011-05-26T16:30:36Z")

</div>

Hi there, I am looking at some old, confusing ruby code that works but  
is really ugly. I'm hoping someone here can help me find a more ruby  
way of rewriting it. Rather than post the ugly code, I'll describe  
what it is trying to do.

The code reads in each line of an array, looks for a closing/ending "  
and puts multiple lines into one element of another array if they are  
part of the same string.

input: data\_array = [ " \"Only one line.\"", " \"line 1 ", " line 2.\"  
" ]

so data\_array.size = 3

> **···**
>
> ----
> 
> > puts data\_array
> 
> "Only one line."  
> "line 1  
> line 2."  
> ----
> 
> I need to bring linked lines together like this:  
> new\_array = [" \"Only one line.\"", " \"line 1 line 2.\" "]
> 
> =\> new\_array.size = 2
> 
> ideas?
> 
> TIA.

---

<div class="post-metadata">

**Author:** ![John\_Morrice](https://avatars.discourse-cdn.com/v4/letter/j/8c91f0/32.png) [@John\_Morrice](https://rubytalk.org/u/John_Morrice)\
**Post date:** [26 May 2011 17:43 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/2 "2011-05-26T17:43:15Z")

</div>

> The code reads in each line of an array, looks for a closing/ending "  
> and puts multiple lines into one element of another array if they are  
> part of the same string.

Do you need to handle nested strings?

Here is a crude solution that doesn't. I tried it on 1.9.2

# The messy input  
mess = [" \"Only one line.\"", " \"line 1 ", " line 2.\""]

# A single string, from the mess concatenated  
single = mess.join ""  
# Find all matches of the regex  
matches = single.scan /("[^"]\*")/  
# Flatten those results,  
# to get lines  
lines = matches.flatten

# Pretty print the lines  
p lines

I don't think any regex, being a finite automaton, could handle nested  
strings properly.

Have you considered writing a small lexer and parser? You may be  
better doing that, can handle weirder strings too.

Cheers,  
Johnny

---

<div class="post-metadata">

**Author:** ![Bala\_TS](https://avatars.discourse-cdn.com/v4/letter/b/f1d935/32.png) [@Bala\_TS](https://rubytalk.org/u/Bala_TS)\
**Post date:** [27 May 2011 04:53 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/3 "2011-05-27T04:53:06Z")

</div>

I think this may be solution about that problem

irb(main):027:0\> a=" "  
=\> " "  
irb(main):028:0\> x=["line 1","line2","line3"]  
=\> ["line 1", "line2", "line3"]  
irb(main):029:0\> x.each do |r|  
irb(main):030:1\* r=a+r  
irb(main):031:1\* a=r+" "  
irb(main):032:1\> end  
=\> ["line 1", "line2", "line3"]  
irb(main):033:0\> puts a  
line 1 line2 line3  
=\> nil  
irb(main):034:0\>

by  
bdeveloper01

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

---

<div class="post-metadata">

**Author:** ![John\_Morrice](https://avatars.discourse-cdn.com/v4/letter/j/8c91f0/32.png) [@John\_Morrice](https://rubytalk.org/u/John_Morrice)\
**Post date:** [26 May 2011 17:54 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/4 "2011-05-26T17:54:13Z")

</div>

> I don't think any regex, being a finite automaton, could handle nested  
> strings properly.

Ignore this bit, it's false.

---

<div class="post-metadata">

**Author:** ![Paul22](https://avatars.discourse-cdn.com/v4/letter/p/e68b1a/32.png) [@Paul22](https://rubytalk.org/u/Paul22)\
**Post date:** [26 May 2011 21:25 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/5 "2011-05-26T21:25:30Z")

</div>

Hi Johnny, thanks for the reply

> Do you need to handle nested strings?

I'm not sure. I don't think so. I think the content is scrubbed  
beforehand to replace all embedded " with '.

> # The messy input  
> mess = [" \"Only one line.\"", " \"line 1 ", " line 2.\""]
> 
> # A single string, from the mess concatenated  
> single = mess.join ""  
> matches = single.scan /("[^"]\*")/  
> lines = matches.flatten
> 
> # Pretty print the lines  
> p lines

I'm not sure about the 'join' solution for 2 reasons:  
1) this array may be 1000's of lines long and I wonder what the  
performance will be like.  
2) I'm thinking about getting rid of the initial array and reading  
the data straight from the input files. In that case, i would have to  
read in each line anyway.

Having said that, I will give this a try and see how it works with the  
test data I have. Thanks!

> Have you considered writing a small lexer and parser? You may be  
> better doing that, can handle weirder strings too.

No I haven't -- I don't know how to do that. yet.

Cheers! Paul.

> **···**
>
> On May 26, 1:43 pm, Johnny Morrice wrote:

---

<div class="post-metadata">

**Author:** ![7stud](https://avatars.discourse-cdn.com/v4/letter/7/57b2e6/32.png) [@7stud](https://rubytalk.org/u/7stud)\
**Post date:** [26 May 2011 22:33 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/6 "2011-05-26T22:33:40Z")

</div>

Johnny M. wrote in post #1001292:

> I don't think any regex, being a finite automaton, could handle nested  
> strings properly.

There are regexes for nested parentheses--they use recursive regexes.

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

---

<div class="post-metadata">

**Author:** ![John\_Morrice](https://avatars.discourse-cdn.com/v4/letter/j/8c91f0/32.png) [@John\_Morrice](https://rubytalk.org/u/John_Morrice)\
**Post date:** [26 May 2011 21:46 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/7 "2011-05-26T21:46:06Z")

</div>

> \> Have you considered writing a small lexer and parser? You may be  
> \> better doing that, can handle weirder strings too.  
> \>
> 
> No I haven't -- I don't know how to do that. yet.

Hey I was brainfarting at that point, you really don't need to do that!  
I brainfart a lot. Should really think for a bit before sending emails  
off...

---

<div class="post-metadata">

**Author:** ![7stud](https://avatars.discourse-cdn.com/v4/letter/7/57b2e6/32.png) [@7stud](https://rubytalk.org/u/7stud)\
**Post date:** [26 May 2011 22:14 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/8 "2011-05-26T22:14:46Z")

</div>

Paul wrote in post #1001335:

> I'm not sure about the 'join' solution for 2 reasons:

Okay. How about:

original\_lines = [  
&nbsp;&nbsp;%q{"Only one line."},  
&nbsp;&nbsp;%q{"line 1 },  
&nbsp;&nbsp;%q{ line 2."},  
]

combined\_lines =   
temp = ''

original\_lines.each do |line|  
&nbsp;&nbsp;temp \<\< line

&nbsp;&nbsp;if temp[-1] == %q{"}  
&nbsp;&nbsp;&nbsp;&nbsp;combined\_lines \<\< temp  
&nbsp;&nbsp;&nbsp;&nbsp;temp = ''  
&nbsp;&nbsp;end  
end

p combined\_lines

--output:--  
["\"Only one line.\"", "\"line 1 line 2.\""]

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

---

<div class="post-metadata">

**Author:** ![7stud](https://avatars.discourse-cdn.com/v4/letter/7/57b2e6/32.png) [@7stud](https://rubytalk.org/u/7stud)\
**Post date:** [26 May 2011 22:31 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/9 "2011-05-26T22:31:01Z")

</div>

Paul wrote in post #1001335:

> 2) I'm thinking about getting rid of the initial array and reading  
> the data straight from the input files.

Okay. How about:

require 'stringio'

str =\<\<'ENDOFSTRING'  
"Only one line."  
"line 1  
line 2  
line 3"  
ENDOFSTRING

file = StringIO.new(str)  
$/ = %Q{"\n} #change input line separator

file.each do |line|  
&nbsp;&nbsp;line.chomp!("\n")  
&nbsp;&nbsp;line.gsub!("\n", ' ')  
&nbsp;&nbsp;p line  
end

--output:--  
"\"Only one line.\""  
"\"line 1 line 2 line 3\""

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

---

<div class="post-metadata">

**Author:** ![Gary\_Wright](https://avatars.discourse-cdn.com/v4/letter/g/58956e/32.png) [@Gary\_Wright](https://rubytalk.org/u/Gary_Wright)\
**Post date:** [26 May 2011 22:45 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/10 "2011-05-26T22:45:06Z")

</div>

You are both right. Johnny is using the formal language definition of  
regular expression while 7stud is using the term to refer to particular  
programming language constructs. Most modern regexp libraries allow  
for patterns that go well beyond the formal language concept of  
regular expressions.

Still, I'm not sure how you would defined nested strings using a single  
quoting character:

"stuff"otherstuff"morestuff"

Is that an example of a nested string or just two strings with otherstuff  
inbetween?

Gary Wright

> **···**
>
> On May 26, 2011, at 6:33 PM, 7stud -- wrote:
> 
> > Johnny M. wrote in post #1001292:
> > 
> > > I don't think any regex, being a finite automaton, could handle nested  
> > > strings properly.
> > 
> > There are regexes for nested parentheses--they use recursive regexes.

---

<div class="post-metadata">

**Author:** ![John\_Morrice](https://avatars.discourse-cdn.com/v4/letter/j/8c91f0/32.png) [@John\_Morrice](https://rubytalk.org/u/John_Morrice)\
**Post date:** [26 May 2011 23:05 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/11 "2011-05-26T23:05:43Z")

</div>

> "stuff"otherstuff"morestuff"
> 
> Is that an example of a nested string or just two strings with  
> otherstuff inbetween?

That's ambiguous. Oh noes!

I am a sort of disorganised person. I was thinking of matching  
parenthesis, which you can't do with "regular" regular expressions.

Really I just made a stupid mistake!  
I was thinking of nested stings like so "\"\\\"\\\"\"".

All you would have to look for is \", since \\\" ends with \". So that  
can be done without variable amounts of memory.

Hence, I sort of just blabbed without engaging the brain properly,  
leading to this discussion. Oh noes!

I'm not really sure why my mind drips out my ears, but hey I have some  
cheese and wrote some ruby so it's all good.

Johnny

---

<div class="post-metadata">

**Author:** ![Paul22](https://avatars.discourse-cdn.com/v4/letter/p/e68b1a/32.png) [@Paul22](https://rubytalk.org/u/Paul22)\
**Post date:** [27 May 2011 04:40 UTC](https://rubytalk.org/t/need-help-bringing-select-array-lines-together/62807/12 "2011-05-27T04:40:29Z")

</div>

That code \_almost\_ works. I changed the one line to "temp[-1,1]" and  
then it worked! =)

This looks exactly like what I need. Thanks!

Cheers! Paul.

> **···**
>
> On May 26, 6:14 pm, 7stud wrote:
> 
> > combined\_lines =   
> > temp = ''
> > 
> > original\_lines.each do |line|  
> > temp \<\< line
> > 
> > if temp[-1] == %q{"}  
> > combined\_lines \<\< temp  
> > temp = ''  
> > end  
> > end
> > 
> > p combined\_lines
> > 
> > --output:--  
> > ["\"Only one line.\"", "\"line 1 line 2.\""]
