# Regexp captures

**URL:** <https://www.ruby-forum.com/t/regexp-captures/83927>\
**Category:** Ruby\
**Created:** [January 30, 2007, 9:25pm UTC](https://www.ruby-forum.com/t/regexp-captures/83927 "2007-01-30T21:25:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![el-gato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e0b2c6/32.png) [@el-gato](https://www.ruby-forum.com/u/el-gato)\
**Post date:** [January 30, 2007, 9:25pm UTC](https://www.ruby-forum.com/t/regexp-captures/83927/1 "2007-01-30T21:25:32Z")

</div>

I find myself doing something like this a lot lately:

# where result is most often the textual output of a %x{command}

(c = result.match(/id: (\d+)/)) ? c.captures.first : result.scan(/error:  
(.\*)/).to\_s

Is there a smoother/better way to say this?

---

<div class="post-metadata">

**Author:** ![el-gato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e0b2c6/32.png) [@el-gato](https://www.ruby-forum.com/u/el-gato)\
**Post date:** [January 31, 2007, 3:11am UTC](https://www.ruby-forum.com/t/regexp-captures/83927/2 "2007-01-31T03:11:19Z")

</div>

On Behalf Of El Gato:

# (c = result.match(/id: (\d+)/)) ? c.captures.first :

# result.scan(/error: (.\*)/).to\_s

why not just build the regex and then capture/match.

irb(main):067:0\> re = /(id|error): ((\d+)|(._))/  
=\> /(id|error): ((\d+)|(._))/  
irb(main):068:0\> result = “id: 1234”  
=\> “id: 1234”  
irb(main):069:0\> c = result.match(re)[2].to\_s  
=\> “1234”  
irb(main):070:0\> result = “error: this is an error”  
=\> “error: this is an error”  
irb(main):071:0\> c = result.match(re)[2].to\_s  
=\> “this is an error”

kind regards -botp

---

<div class="post-metadata">

**Author:** ![el-gato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e0b2c6/32.png) [@el-gato](https://www.ruby-forum.com/u/el-gato)\
**Post date:** [January 31, 2007, 11:45am UTC](https://www.ruby-forum.com/t/regexp-captures/83927/3 "2007-01-31T11:45:53Z")

</div>

On 30.01.2007 21:25, El Gato wrote:

> I find myself doing something like this a lot lately:
> 
> # where result is most often the textual output of a %x{command}
> 
> (c = result.match(/id: (\d+)/)) ? c.captures.first : result.scan(/error:  
> (.\*)/).to\_s
> 
> Is there a smoother/better way to say this?

Yes. Use String#[]:

your\_match = result[/id: (\d+)/, 1] || result[/error: (.\*)/, 1]

Note: your second part “result.scan” will always return at most one  
match because of “.\*”. That’s the reason why a single match like mine  
yields the same output.

Other alternatives:

This one is more interesting if you extract different portions of the  
match:

your\_match = case result  
when /id: (\d+)/  
$1  
when /error: (.\*)/  
$1  
else  
nil  
end

In your case you can have it simpler:

your\_result = /id: (\d+)/ =~ result || /error: (.\*)/ =~ result ? $1 :  
nil

But I’d prefer the first variant. 🙂

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![el-gato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/e0b2c6/32.png) [@el-gato](https://www.ruby-forum.com/u/el-gato)\
**Post date:** [January 31, 2007, 8:33pm UTC](https://www.ruby-forum.com/t/regexp-captures/83927/4 "2007-01-31T20:33:52Z")

</div>

Robert K. wrote:

> Yes. Use String#[]:
> 
> your\_match = result[/id: (\d+)/, 1] || result[/error: (.\*)/, 1]
> 
> Note: your second part “result.scan” will always return at most one  
> match because of “.\*”. That’s the reason why a single match like mine  
> yields the same output.
> 
> Other alternatives:
> 
> This one is more interesting if you extract different portions of the  
> match:
> 
> But I’d prefer the first variant. 🙂
> 
> Kind regards
> 
> robert

Wow! Thanks a bunch Robert. I had never seen String#[] before. That’s  
a lot cleaner than my version. I appreciate the help and input from  
both of you.
