Concatenation of regular expressions


#1

Is there a way to concatenate regular expressions in ruby? Something
like Regexp.union but without the or between expressions.

For example say i have the following regular expressions:

Set = /[[][1-9][\d][]]/
Field = /[F][S]?[1-9][\d]*/

and i want to make a regular expression to match both of them, i’d like
to be able to do something like the following:

SetThenField = Set + /([\s])*/ + Field + /[\s]/

  • Geoff

#2

On Mar 27, 2006, at 1:13 PM, Geoff wrote:

to be able to do something like the following:

SetThenField = Set + /([\s])*/ + Field + /[\s]/

  • Geoff

Easy enough:

irb(main):010:0> SetThenField = Regexp.new(Set.to_s + '([\s])’ +
Field.to_s + ‘[\s]’)
=> /(?-mix:[[][1-9][\d][]])([\s])
(?-mix:[F][S]?[1-9][\d]*)[\s]/

Just be careful with the string literal parts of the regexp


#3

On Tue, 28 Mar 2006, Geoff wrote:

SetThenField = Set + /([\s])*/ + Field + /[\s]/

  • Geoff

you could do (untested)

def re_union *res
Regexp::new res.flatten.map{|re| re.source}.join
end

regards.

-a


#4

On 27 Mar 2006 10:09:41 -0800, Geoff removed_email_address@domain.invalid wrote:

Is there a way to concatenate regular expressions in ruby? Something
like Regexp.union but without the or between expressions.

Here’s a little addition (bad pun) for the Regexp class:

class Regexp
def +(re)
Regexp.new self.to_s + re.to_s
end
end

The #to_s method preserves option semantics.

andrew


#5

Hi –

On Tue, 28 Mar 2006, Geoff wrote:

Is there a way to concatenate regular expressions in ruby? Something
like Regexp.union but without the or between expressions.

For example say i have the following regular expressions:

Set = /[[][1-9][\d][]]/
Field = /[F][S]?[1-9][\d]*/

You don’t need character classes for single characters:

Set = /[[1-9]\d]/
Field = /FS?[1-9]\d*/

and i want to make a regular expression to match both of them, i’d like
to be able to do something like the following:

SetThenField = Set + /([\s])*/ + Field + /[\s]/

How about:

SetThenField = /#{Set}(\s)*#{Field}\s/

(This is all untested but it might point you in a helpful direction.)

David


David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” chapters now available
from Manning Early Access Program! http://www.manning.com/books/black


#6

You don’t need character classes for single characters:
Set = /[[1-9]\d]/
Field = /FS?[1-9]\d*/
Makes for slightly better looking expressions. I thought this was the
case, but didn’t bother to check.

How about:
SetThenField = /#{Set}(\s)*#{Field}\s/
(This is all untested but it might point you in a helpful direction.)
Seems to work actually. I had found an old groups post about using #{}
within regular expressions but didn’t bother to try it because of the
way they had explained it.

irb(main):009:0> re1 = /[\w]+/
=> /[\w]+/
irb(main):010:0> re2 = /[\d]+/
=> /[\d]+/
irb(main):017:0> “Foo 123”.match(/#{re1}[\s]+#{re2}/).to_s
=> “Foo 123”

Thanks,

  • Geoff

#7

I was thinking of doing it this way but it seems somewhat unruby. From
these responces though it looks like i’ll have to tack some tiny method
on to regexp to achieve this, i was hoping that this functionality was
a part of regexp (or somewhere else in ruby) and that i had just missed
it.

  • Geoff