leifericf
leifericf

Reputation: 2372

How to split a string in Ruby into two variables in one line of code?

In Ruby, how can I split a string into two variables in one line of code?

Example:

Goal: Split string s into variables a and b, such that a = 'A' and b = 123.

irb(main):001:0> s = "A123" # Create string to split.
=> "A123"

irb(main):002:0> a, b = s.split(/\d/) # Extracts letter only.
=> ["A"]

irb(main):003:0> puts a # a got assigned 'A' as expected.
A
=> nil

irb(main):004:0> puts b # b did not get assigned the split remainder, '123'.
=> nil

irb(main):005:0> b = s.split(/\D/) # Extracts number only.
=> ["", "123"]

irb(main):006:0> puts b # Now b has the value I want it to have.
123
=> nil

How can the same result be achieved in one line of code?

Upvotes: 3

Views: 3696

Answers (3)

Stefan
Stefan

Reputation: 114168

Another one via MatchData#to_a:

_, a, b = * "AB123".match(/(\D+)(\d+)/)
#=> ["AB123", "AB", "123"]

a #=> "AB"
b #=> "123"

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626794

Instead of splitting with lookaheads and lookbehinds, you may scan the string to tokenize it into digits and non-digits with /\d+|\D+/:

"AB123".scan(/\d+|\D+/)
# => [AB, 123]

The pattern matches

  • \d+ - 1 or more digits
  • | - or
  • \D+ - 1 or more chars other than digit.

Upvotes: 5

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

There are many ways, e.g. positive lookbehind in this particular case would do:

a, b = 'A123'.split(/(?<=\D)/)
#⇒ ["A", "123"]

Positive lookahead with a limit of slices:

'AB123'.split(/(?=\d)/, 2)
#⇒ ["AB", "123"]

By indices:

[0..1, 2..-1].map &'AB123'.method(:[])
#⇒ ["AB", "123"]

Upvotes: 10

Related Questions