3

I'm relatively new to ruby and I'm trying to figure out the "ruby" way of extracting multiple values from a string, based on grouping in regexes. I'm using ruby 1.8 (so I don't think I have named captures).

I could just match and then assign $1,$2 - but I feel like there's got to be a more elegant way (this is ruby, after all).

I've also got something working with grep, but it seems hackish since I'm using an array and just grabbing the first element:

input="FOO: 1 BAR: 2"
foo, bar = input.grep(/FOO: (\d+) BAR: (\d+)/){[$1,$2]}[0]
p foo
p bar

I've tried searching online and browsing the ruby docs, but haven't been able to figure anything better out.

3 Answers 3

5

Rubys String#match method returns a MatchData object with the method captures to return an Array of captures.

>> string = "FOO: 1 BAR: 2"
=> "FOO: 1 BAR: 2"
>> string.match /FOO: (\d+) BAR: (\d+)/
=> #<MatchData "FOO: 1 BAR: 2" 1:"1" 2:"2">
>> _.captures
=> ["1", "2"]
>> foo, bar = _
=> ["1", "2"]
>> foo
=> "1"
>> bar
=> "2"

To Summarize:

foo, bar = input.match(/FOO: (\d+) BAR: (\d+)/).captures
Sign up to request clarification or add additional context in comments.

2 Comments

So something like foo, bar = input.match(/FOO: (\d+) BAR: (\d+)/).captures? Definitely more readable
Nice timing, I literally just altered my original post with the same thing. Yep, that'll do it.
1

Either:

foo, bar = string.scan(/[A-Z]+: (\d+)/).flatten

or:

foo, bar = string.match(/FOO: (\d+) BAR: (\d+)/).captures

Comments

1

Use scan instead:

input="FOO: 1 BAR: 2"

input.scan(/FOO: (\d+) BAR: (\d+)/) #=> [["1", "2"]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.