# Suggestions for a parsing strategy?

**URL:** <https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483>\
**Category:** Ruby\
**Created:** [July 19, 2008, 5:05am UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483 "2008-07-19T05:05:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 5:05am UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/1 "2008-07-19T05:05:49Z")

</div>

Hi all,

I have input strings that can look like this:

Common, Commerc(e, ial)

I need to parse these into the three words that this represents:

Common, Commerce, Commercial.

I’m a little new to ruby, and hence wondering what direction would be  
best to go in? (.scan, regexes … something else?) For me, the  
complication I’m not sure how to deal with is the two “levels” of the  
comma as a separator.

Thanks,  
Robb

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 5:13am UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/2 "2008-07-19T05:13:25Z")

</div>

On Friday 18 July 2008 21:59:56 Robb wrote:

> I’m a little new to ruby, and hence wondering what direction would be  
> best to go in? (.scan, regexes … something else?) For me, the  
> complication I’m not sure how to deal with is the two “levels” of the  
> comma as a separator.

One way would be to find the exceptions first. Replace anything that  
matches  
the

Commerc(e, ial)

pattern with the two words, as the literal string “Commerce,  
Commercial”. Then  
you can just do a simple split on the commas, and maybe strip  
whitespace.

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 5:44am UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/3 "2008-07-19T05:44:24Z")

</div>

On Fri, Jul 18, 2008 at 10:59 PM, Robb [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi all,
> 
> I have input strings that can look like this:
> 
> Common, Commerc(e, ial)
> 
> I need to parse these into the three words that this represents:
> 
> Common, Commerce, Commercial.

This code does a lot of what you describe, providing the parenthetical  
only appears at the end.

====

s = “Common, Commerc(e, ial), Computer, Con(ic, ehead, temporary)”

def parse\_word\_list(s)  
s.scan(/(\w+)(((.\*?)))?/).map { |root, junk, suffixes|  
[root, suffixes && suffixes.split(", ")]  
}  
end

list = parse\_word\_list(s)

# see what’s produced

p list

# use it to generate all words

list.each do |root, suffix\_list|  
if suffix\_list  
suffix\_list.each do |suffix|  
puts “#{root}#{suffix}”  
end  
else  
puts root  
end  
end

====

Hope that helps,

Eric

====

[LearnRuby.com](http://LearnRuby.com) offers Rails & Ruby HANDS-ON public & ON-SITE workshops.  
Please visit [http://LearnRuby.com](http://LearnRuby.com) for all the details.

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 6:25am UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/4 "2008-07-19T06:25:57Z")

</div>

On Friday 18 July 2008 22:38:43 Eric I. wrote:

> s.scan(/(\w+)(((.\*?)))?/).map { |root, junk, suffixes|

This pattern looks really useful… Looking at the docs for scan, it  
looks  
like it can take a block.

Which just leaves one question: Why isn’t this an Enumerator in Ruby  
1.9? I  
don’t think the original meaning (of producing an array) is made much  
more  
difficult by the form

s.scan(/…/).to\_a

And I suspect that it would most often be useful for things like #map,  
if not  
used in block form outright. Making it an Enumerator would be somewhat  
more  
efficient than building a whole array first – and more responsive, if  
it’s a  
large string.

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 1:45pm UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/5 "2008-07-19T13:45:20Z")

</div>

On Jul 19, 11:38 am, “Eric I.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> s.scan(/(\w+)(((.\*?)))?/).map { |root, junk, suffixes|

s.scan(/(\w+)(?:((.\*?)))?/) can avoid the “junk”  
^^,Your pattern is great & helpful

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 1:07pm UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/6 "2008-07-19T13:07:28Z")

</div>

David M. wrote:

> Why isn’t [the return value of scan] an Enumerator in Ruby 1.9?

Or 1.8.7 for that matter. Yes, I’ve been asking myself this very same  
question  
since the release of 1.9.

> And I suspect that it would most often be useful for things like #map, if  
> not used in block form outright. Making it an Enumerator would be somewhat  
> more efficient than building a whole array first – and more responsive, if  
> it’s a large string.

Also it’d allow you to use the matchdata object inside map if you need  
to. The  
way it is now you’d have to do:  
string.enum\_for(:scan,/re/).map do  
md = Regexp.last\_match  
do\_something\_with md  
end

instead of just  
string.scan.map do…end

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [July 19, 2008, 2:05pm UTC](https://www.ruby-forum.com/t/suggestions-for-a-parsing-strategy/143483/7 "2008-07-19T14:05:48Z")

</div>

> Making it an Enumerator would be somewhat more  
> efficient than building a whole array first – and more responsive, if it’s a  
> large string.

There is also the StringScanner class that can be used to return one  
match at a time.
