Reputation: 2372
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
Reputation: 114168
Another one via MatchData#to_a
:
_, a, b = * "AB123".match(/(\D+)(\d+)/)
#=> ["AB123", "AB", "123"]
a #=> "AB"
b #=> "123"
Upvotes: 1
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
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