Forum: Ruby combine two regular expressions

Posted by Ken Paul (kenfc)
on 2013-03-16 06:29
Hi there,

How to combine the two regular expressions into one?

reg1 = /\w+[_][0-9]+$/
reg2 = /\w+$/

it seems that match(/\w+\([_][0-9]+\)?$/ does not work, any idea?
Posted by Matthew Kerwin (mattyk)
on 2013-03-16 07:01
Ken Paul wrote in post #1101884:
> Hi there,
>
> How to combine the two regular expressions into one?
>
> reg1 = /\w+[_][0-9]+$/
> reg2 = /\w+$/
>
> it seems that match(/\w+\([_][0-9]+\)?$/ does not work, any idea?

A couple of things:

* \( and \) match literal '(' and ')' characters.  In Ruby regex you
  use unescaped parentheses to mark subpatterns/groups, thus:  /a(bc)d/

So:  /\w+([_][0-9]+)?$/

Also:
* [_] doesn't need to be in a character class, /[_]/ matches the same
  as /_/
* there's a special regex metacharacter \d that matches exactly [0-9]

So you could use:
  reg1 = /\w+_\d+$/
  reg2 = /\w+$/
  regX = /\w+(_\d+)?$/

Although that already looks a bit less readable than your way...

Also:
* \w matches underscores and digits as well as letters, so /\w+/ already
  matches /_[0-9]+/  (in other words, reg2 will already match everything
  you intended from the combined pattern)

irb> s = 'hello_world_123'
=> "hello_world"123"
irb> m = s.match /\w+$/
=> #<MatchData "hello_world_123">
irb> m[0]
=> "hello_world_123"

However, assuming you want to explicitly match /_[0-9]+/ at the end
separately, you could use:

irb> m = s.match /\w+?(_\d+)?$/
=> #<MatchData "hello_world_123" 1:"_123">
irb> m[1]
=> "_123"

Note the question mark after \w+? , it makes it un-greedy (i.e. it
doesn't gobble up the entire rest of the string, the way \w+ would).

Or assuming you actually want to match LETTER+ [ "_" NUMBER+ ] you could
use:

irb> m = s.match /[A-Za-z]+(_\d+)?$/
=> #<MatchData "world_123" 1:"_123">

Note how it didn't match "hello_" since that contains non-letters.  Or
various other combinations and permutations.

All this gleaned from http://www.ruby-doc.org/core-1.9.3/Regexp.html (as
well as a couple of decades playing with regular expressions.)
Posted by Ken Paul (kenfc)
on 2013-03-16 07:39
This is a splendid answer, thanks for all the insights.
Posted by Matthew Kerwin (mattyk)
on 2013-03-16 07:49
Ken Paul wrote in post #1101887:
> This is a splendid answer, thanks for all the insights.

No worries.
Posted by Love U Ruby (my-ruby)
on 2013-03-16 08:32
Ken Paul wrote in post #1101887:
> This is a splendid answer, thanks for all the insights.

Yes @ Matthew Kerwin is awesome to deliver the things from the very 
basic. I like this one. :)
Posted by Joel Pearson (virtuoso)
on 2013-03-16 11:07
It depends what you mean by combine. If you want to match either then 
you could use the pipe "|" character as an "or" operator.
Posted by "Jesús Gabriel y Galán" <jgabrielygalan@gmail.com> (Guest)
on 2013-03-16 12:34
(Received via mailing list)
On Sat, Mar 16, 2013 at 11:08 AM, Joel Pearson <lists@ruby-forum.com> 
wrote:
> It depends what you mean by combine. If you want to match either then
> you could use the pipe "|" character as an "or" operator.

And if you have to work with the original regexps, you can use the
method Regexp#union:

http://ruby-doc.org/core-2.0/Regexp.html#method-c-union

Jesus.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.